Kbase P24794: How to read information from a Primary Domain Controller (PDC) using 4GL and WIN32 API.
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  2/16/2005 |
|
Status: Verified
GOAL:
How to read information from a Primary Domain Controller (PDC) using 4GL and WIN32 API.
GOAL:
How to read information from the Active Directory using 4GL
GOAL:
How to make WIN32 API calls to netapi32.dll in 4GL
GOAL:
How to use the NetUserGetInfo WIN32 API function in 4GL
FACT(s) (Environment):
Progress 9.1D
Windows NT 32 Intel/Windows 2000
FIX:
The following program gives you an example on how to read user account information from the Active Directory or PDC. For more information please refer to the Microsoft MSDN website at http://www.msdn.com .
FUNCTION convU2A RETURNS CHARACTER
( INPUT iBufstr AS INTEGER ) FORWARD.
DEFINE VARIABLE pBufstr AS MEMPTR NO-UNDO.
DEFINE VARIABLE iBufstr AS INTEGER NO-UNDO.
DEFINE VARIABLE iRes AS INTEGER NO-UNDO.
DEFINE VARIABLE cDCName AS CHARACTER NO-UNDO.
DEFINE VARIABLE cUsrname AS CHARACTER FORMAT "X(20)" NO-UNDO.
DEFINE VARIABLE pUsrname AS MEMPTR NO-UNDO.
DEFINE VARIABLE dDateInit AS DATE INITIAL "1/1/1970" NO-UNDO.
/* Get the name of the primary domain controller */
RUN NetGetDCName(
INPUT 0,
INPUT 0,
OUTPUT iBufstr,
OUTPUT iRes
).
IF iRes = 0 THEN SET-POINTER-VALUE(pBufstr) = iBufstr.
/* Convert the Unicode string to Ansi format */
cDCName = convU2A(iBufstr).
/* Specify username to query */
cUsrname = "Administrator".
/* Convert username string from Ansi to Unicode format */
RUN convA2U(INPUT cUsrname, OUTPUT pUsrname).
/* Retrieve information about the username */
RUN NetUserGetInfo(
INPUT iBufstr,
INPUT GET-POINTER-VALUE(pUsrname),
INPUT 3,
OUTPUT iBufstr,
OUTPUT iRes
).
/* Free Buffer if set */
IF GET-POINTER-VALUE(pBufstr) <> 0 THEN RUN NetApiBufferFree(pBufstr).
/* Display information */
IF iRes = 0 THEN DO:
SET-POINTER-VALUE(pBufstr) = iBufstr.
/* Each member of the structure takes 4 bytes: */
/* Member position = ((member# - 1) * 4) + 1 */
/* 1, 5, 9, etc. */
MESSAGE
"DC Name: " cDCName SKIP
"Username: " convU2A(GET-LONG(pBufstr,1)) SKIP
"Last Logon: " dDateinit + TRUNCATE((GET-LONG(pBufstr,53) / 86400),0) SKIP
"Last Password Change: " TODAY - TRUNCATE(GET-LONG(pBufstr,9) / 86400,0) SKIP
"Account Comments: " convU2A(GET-LONG(pBufstr,21))
VIEW-AS ALERT-BOX INFO BUTTONS OK.
IF GET-POINTER-VALUE(pBufstr) <> 0 THEN RUN NetApiBufferFree(pBufstr).
END.
ELSE CASE iRes:
WHEN 2221 THEN MESSAGE "The user name could not be found."
VIEW-AS ALERT-BOX INFO BUTTONS OK.
WHEN 2351 THEN MESSAGE "The computer name is invalid."
VIEW-AS ALERT-BOX INFO BUTTONS OK.
WHEN 5 THEN MESSAGE "The user does not have access to the requested information."
VIEW-AS ALERT-BOX INFO BUTTONS OK.
OTHERWISE MESSAGE "Error Code: " iRes
VIEW-AS ALERT-BOX INFO BUTTONS OK.
END CASE.
SET-SIZE(pUsrName) = 0.
/**************************************************************/
/* Functions an.d Procedures */
/**************************************************************/
/* Converts Unicode string to Ansi format */
/* Only valid for characters with a value of < 128 */
FUNCTION convU2A RETURNS CHARACTER
( INPUT iBufstr AS INTEGER ) :
DEFINE VARIABLE cString AS CHARACTER NO-UNDO.
DEFINE VARIABLE iPos AS INTEGER INITIAL 1 NO-UNDO.
DEFINE VARIABLE pBufstr AS MEMPTR NO-UNDO.
SET-POINTER-VALUE(pBufstr) = iBufstr.
cString = "".
DO WHILE GET-BYTE(pBufstr,ipos) <> 0:
cString = cString + CHR(GET-BYTE(pBufstr,ipos)).
ipos = ipos + 2.
END.
RETURN cString.
END FUNCTION.
/* Converts Ansi string to Unicode format */
/* Only valid for characters with a value of < 128 */
PROCEDURE convA2U:
DEFINE INPUT PARAMETER cString AS CHARACTER.
DEFINE OUTPUT PARAMETER pString AS MEMPTR.
DEFINE VARIABLE iString AS INTEGER NO-UNDO.
DEFINE VARIABLE iPos AS INTEGER INITIAL 1 NO-UNDO.
DEFINE VARIABLE iCnt AS INTEGER INITIAL 1 NO-UNDO.
iString = LENGTH(cString) * 2 + 1.
SET-SIZE(pString) = iString.
PUT-STRING(pString,1) = FILL(CHR(0), iString).
DO WHILE iPos < iString:
PUT-BYTE(pString,iPos) = ASC(SUBSTRING(cString,iCnt,1)).
iCnt = iCnt + 1.
iPos = iPos + 2.
END.
END PROCEDURE.
/**************************************************************/
/**************************************************************/
/* External Procedures */
/**************************************************************/
PROCEDURE NetGetDCName EXTERNAL "netapi32.dll":
DEFINE INPUT PARAMETER servername AS LONG.>
DEFINE INPUT PARAMETER domainname AS LONG.
DEFINE OUTPUT PARAMETER bufstr AS LONG.
DEFINE RETURN PARAMETER retcode AS LONG.
END.
PROCEDURE NetUserGetInfo EXTERNAL "netapi32.dll":
DEFINE INPUT PARAMETER servername AS LONG.
DEFINE INPUT PARAMETER username AS LONG.
DEFINE INPUT PARAMETER level AS LONG.
DEFINE OUTPUT PARAMETER bufstr AS LONG.
DEFINE RETURN PARAMETER retcode AS LONG.
END.
PROCEDURE NetApiBufferFree EXTERNAL "NETAPI32.DLL":
DEFINE INPUT PARAMETER bufstr AS MEMPTR NO-UNDO.
END PROCEDURE.
/**************************************************************/
.