mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
817 lines
20 KiB
817 lines
20 KiB
/*
|
|
*
|
|
* In order to test rpc bind caching as best as we can, the cache limit
|
|
* is set to 3, and then we attempt to bind to four services. So that
|
|
* it forces one handle out of the cache each time.
|
|
*
|
|
* If we have multiple threads doing this at the same time, then we may
|
|
* randomly get the use counts up to something other than zero. This
|
|
* way, some of the other caching logic can be exercised.
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
|
|
//----------
|
|
// Includes
|
|
//----------
|
|
#include <nt.h> // DbgPrint prototype
|
|
#include <ntrtl.h> // DbgPrint prototype
|
|
#include <nturtl.h> // needed for winbase.h
|
|
|
|
#include <stdlib.h> // atoi
|
|
#include <stdio.h> // printf
|
|
#include <string.h> // strcmp
|
|
#include <conio.h> // getch
|
|
#include <lmerr.h> // NERR_ error codes
|
|
#include <windows.h> // win32 typedefs
|
|
#include <lmcons.h>
|
|
#include <lmshare.h> // NetShareEnum
|
|
#include <lmremutl.h> // NetRemoteTOD
|
|
#include <lmuse.h> // NetUseEnum
|
|
#include <lmmsg.h> // NetMessageNameEnum
|
|
#include <lmapibuf.h> // NetApiBufferFree
|
|
#include <tstring.h> // Unicode
|
|
|
|
//---------------------------
|
|
// DEFINES
|
|
//---------------------------
|
|
#define RETURN_ALL 0xffffffff
|
|
|
|
//---------------------------
|
|
// GLOBALS
|
|
//---------------------------
|
|
|
|
LPTSTR GlobalServerName; // Passed in ServerName
|
|
DWORD GlobalLoopCount; // Number of times for each thread to loop
|
|
|
|
//---------------------------
|
|
// Local Function Prototypes
|
|
//---------------------------
|
|
VOID
|
|
BindCachingTest(
|
|
DWORD ThreadNum,
|
|
DWORD LoopCount,
|
|
LPTSTR ServerName
|
|
);
|
|
|
|
DWORD
|
|
StartThread(
|
|
LPVOID ThreadNum
|
|
);
|
|
|
|
VOID
|
|
BindCachingTest2(
|
|
DWORD ThreadNum,
|
|
DWORD LoopCount,
|
|
LPTSTR ServerName
|
|
);
|
|
|
|
BOOL
|
|
ConvertToUnicode(
|
|
OUT LPWSTR *UnicodeOut,
|
|
IN LPSTR AnsiIn
|
|
);
|
|
|
|
VOID
|
|
SingleServiceTest(
|
|
VOID
|
|
);
|
|
|
|
|
|
/***************************************************************************/
|
|
VOID _CRTAPI1
|
|
main (
|
|
DWORD argc,
|
|
PCHAR argv[]
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
Note:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD rc;
|
|
DWORD threadId;
|
|
HANDLE threadHandles[200];
|
|
DWORD NumThreads;
|
|
DWORD i;
|
|
|
|
if (argc < 2) {
|
|
printf("ERROR: must supply a num Threads. ServerName Optional\n");
|
|
printf("bindtest 2 \\\\DANL2 2\n");
|
|
printf("bindtest 2 ONE_API /t- multiple calls to only one service\n");
|
|
return;
|
|
}
|
|
|
|
NumThreads = atol(argv[1]);
|
|
|
|
GlobalLoopCount = 1;
|
|
|
|
if (argc > 2 ) {
|
|
#ifdef UNICODE
|
|
ConvertToUnicode ((LPWSTR *)&GlobalServerName, argv[2]);
|
|
#else
|
|
GlobalServerName = argv[2];
|
|
#endif
|
|
//
|
|
// Look for a special server name "ONE_API". If this name is
|
|
// found it means that we should do a single test with a single
|
|
// service - so se can play with the state of the service between
|
|
// bindings.
|
|
//
|
|
if (_wcsicmp(GlobalServerName, L"ONE_API") ==0) {
|
|
SingleServiceTest();
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
GlobalServerName = NULL;
|
|
}
|
|
|
|
//------------------------------
|
|
// Do Serial Thread Tests
|
|
//------------------------------
|
|
printf("Starting Serial Test\n");
|
|
threadHandles[0] = CreateThread(
|
|
NULL,
|
|
0L,
|
|
(LPTHREAD_START_ROUTINE)StartThread,
|
|
(LPVOID)0,
|
|
0L,
|
|
&threadId);
|
|
|
|
if(threadHandles[0] == NULL) {
|
|
printf("CreateThread failed %d\n",GetLastError());
|
|
}
|
|
else {
|
|
printf("Thread #%d Created\n",0);
|
|
}
|
|
rc = WaitForSingleObject(threadHandles[0], 60000);
|
|
|
|
printf("Creating 2nd thread for Serial Test\n");
|
|
threadHandles[0] = CreateThread(
|
|
NULL,
|
|
0L,
|
|
(LPTHREAD_START_ROUTINE)StartThread,
|
|
(LPVOID)0,
|
|
0L,
|
|
&threadId);
|
|
|
|
if(threadHandles[0] == NULL) {
|
|
printf("CreateThread failed %d\n",GetLastError());
|
|
}
|
|
else {
|
|
printf("Thread #%d Created\n",0);
|
|
}
|
|
rc = WaitForSingleObject(threadHandles[0], 60000);
|
|
|
|
printf("Serial Test Done - Starting Simultaneous Test\n\n");
|
|
//------------------------------
|
|
// Do Simultaneous Thread Tests
|
|
//------------------------------
|
|
for(i=0; i<NumThreads; i++) {
|
|
|
|
threadHandles[i] = CreateThread(
|
|
NULL,
|
|
0L,
|
|
(LPTHREAD_START_ROUTINE)StartThread,
|
|
(LPVOID)i,
|
|
0L,
|
|
&threadId);
|
|
|
|
if(threadHandles[i] == NULL) {
|
|
printf("CreateThread failed %d\n",GetLastError());
|
|
}
|
|
else {
|
|
printf("Thread #%d Created\n",i);
|
|
}
|
|
}
|
|
|
|
rc = WaitForMultipleObjects(
|
|
NumThreads,
|
|
threadHandles,
|
|
TRUE, // Wait for all to complete
|
|
60000); // Wait for one minute
|
|
|
|
printf("BindCachingTestDone!\n");
|
|
|
|
return;
|
|
}
|
|
|
|
DWORD
|
|
StartThread(
|
|
LPVOID ThreadNum
|
|
)
|
|
{
|
|
//
|
|
// All odd numbered Threads will run Test#2.
|
|
//
|
|
|
|
if ((DWORD)ThreadNum & 1) {
|
|
BindCachingTest2((DWORD)ThreadNum, GlobalLoopCount, GlobalServerName);
|
|
}
|
|
else {
|
|
BindCachingTest((DWORD)ThreadNum, GlobalLoopCount, GlobalServerName);
|
|
}
|
|
ExitThread(0);
|
|
return(0);
|
|
}
|
|
|
|
|
|
VOID
|
|
BindCachingTest(
|
|
IN DWORD ThreadNum,
|
|
IN DWORD LoopCount,
|
|
IN LPTSTR ServerName)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
Note:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
NET_API_STATUS rc;
|
|
DWORD entriesRead;
|
|
DWORD totalEntries;
|
|
DWORD resumeHandle;
|
|
LPBYTE bufPtr;
|
|
PTIME_OF_DAY_INFO pTOD;
|
|
|
|
|
|
do {
|
|
//-------------------------------------
|
|
// WORKSTATION: NetUseEnum
|
|
//-------------------------------------
|
|
printf("%d:NetUse\n",ThreadNum);
|
|
|
|
rc = NetUseEnum(
|
|
ServerName,
|
|
2,
|
|
&bufPtr,
|
|
RETURN_ALL,
|
|
&entriesRead,
|
|
&totalEntries,
|
|
&resumeHandle);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetUseEnum failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
printf("%d:NetUse done\n",ThreadNum);
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
//--------------------------
|
|
// SERVER: NetShareEnum
|
|
//--------------------------
|
|
printf("%d:NetShare\n",ThreadNum);
|
|
|
|
rc = NetShareEnum(
|
|
ServerName,
|
|
2,
|
|
&bufPtr,
|
|
RETURN_ALL,
|
|
&entriesRead,
|
|
&totalEntries,
|
|
&resumeHandle);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetShareEnum failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
printf("%d:NetShare done\n",ThreadNum);
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
|
|
//--------------------------------
|
|
// MESSENGER: NetMessageNameEnum
|
|
//--------------------------------
|
|
printf("%d:NetMessageName\n",ThreadNum);
|
|
rc = NetMessageNameEnum(
|
|
NULL,
|
|
1,
|
|
&bufPtr,
|
|
RETURN_ALL,
|
|
&entriesRead,
|
|
&totalEntries,
|
|
&resumeHandle);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetMessageNameEnum failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
printf("%d:NetMessageName done\n",ThreadNum);
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
|
|
Sleep(200);
|
|
|
|
//--------------------------------
|
|
// TIMESOURCE: NetRemoteTOD
|
|
//--------------------------------
|
|
printf("%d:NetRemoteTOD\n",ThreadNum);
|
|
rc = NetRemoteTOD (
|
|
ServerName,
|
|
&bufPtr);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetRemoteTOD failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
pTOD = (PTIME_OF_DAY_INFO)bufPtr;
|
|
printf("ThreadNum %d - - - Time %d:%d:%d, Day %d/%d/%d\n",
|
|
ThreadNum,
|
|
pTOD->tod_hours,
|
|
pTOD->tod_mins,
|
|
pTOD->tod_secs,
|
|
pTOD->tod_month,
|
|
pTOD->tod_day,
|
|
pTOD->tod_year);
|
|
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
//----------------------------------------
|
|
// SERVER: NetShareEnum (NULL ServerName)
|
|
//----------------------------------------
|
|
printf("%d:NetShare\n",ThreadNum);
|
|
|
|
rc = NetShareEnum(
|
|
NULL,
|
|
2,
|
|
&bufPtr,
|
|
RETURN_ALL,
|
|
&entriesRead,
|
|
&totalEntries,
|
|
&resumeHandle);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetShareEnum failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
printf("%d:NetShare done\n",ThreadNum);
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
|
|
Sleep(200);
|
|
//---------------------------------------------
|
|
// MESSENGER: NetMessageNameEnum
|
|
// This time it should re-use the bind handle.
|
|
//---------------------------------------------
|
|
printf("%d:NetMessageName\n",ThreadNum);
|
|
rc = NetMessageNameEnum(
|
|
NULL,
|
|
1,
|
|
&bufPtr,
|
|
RETURN_ALL,
|
|
&entriesRead,
|
|
&totalEntries,
|
|
&resumeHandle);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetMessageNameEnum failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
printf("%d:NetMessageName done\n",ThreadNum);
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
|
|
|
|
//--------------------------------
|
|
// TIMESOURCE: NetRemoteTOD
|
|
//--------------------------------
|
|
printf("%d:NetRemoteTOD\n",ThreadNum);
|
|
rc = NetRemoteTOD (
|
|
ServerName,
|
|
&bufPtr);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetRemoteTOD failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
pTOD = (PTIME_OF_DAY_INFO)bufPtr;
|
|
printf("ThreadNum %d - - - Time %d:%d:%d, Day %d/%d/%d\n",
|
|
ThreadNum,
|
|
pTOD->tod_hours,
|
|
pTOD->tod_mins,
|
|
pTOD->tod_secs,
|
|
pTOD->tod_month,
|
|
pTOD->tod_day,
|
|
pTOD->tod_year);
|
|
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
LoopCount--;
|
|
}
|
|
while (LoopCount > 0);
|
|
|
|
printf("Thread #%d Done\n",ThreadNum);
|
|
}DWORD
|
|
StartThread2(
|
|
LPVOID ThreadNum
|
|
)
|
|
{
|
|
BindCachingTest((DWORD)ThreadNum, GlobalLoopCount, GlobalServerName);
|
|
ExitThread(0);
|
|
return(0);
|
|
}
|
|
|
|
|
|
VOID
|
|
BindCachingTest2(
|
|
IN DWORD ThreadNum,
|
|
IN DWORD LoopCount,
|
|
IN LPTSTR ServerName)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This test is just like #1 except that it does a call to ServerEnum
|
|
before doing the rest of the test. The idea is that this thread
|
|
should get around the binding to NetUse after the first thread
|
|
(Test1) has a valid handle for the NetUse.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
Note:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
NET_API_STATUS rc;
|
|
DWORD entriesRead;
|
|
DWORD totalEntries;
|
|
DWORD resumeHandle;
|
|
LPBYTE bufPtr;
|
|
PTIME_OF_DAY_INFO pTOD;
|
|
|
|
|
|
do {
|
|
//--------------------------
|
|
// SERVER: NetShareEnum
|
|
//--------------------------
|
|
printf("%d:NetShare\n",ThreadNum);
|
|
|
|
rc = NetShareEnum(
|
|
ServerName,
|
|
2,
|
|
&bufPtr,
|
|
RETURN_ALL,
|
|
&entriesRead,
|
|
&totalEntries,
|
|
&resumeHandle);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetShareEnum failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
printf("%d:NetShare done\n",ThreadNum);
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
|
|
//-------------------------------------
|
|
// WORKSTATION: NetUseEnum
|
|
//-------------------------------------
|
|
printf("%d:NetUse\n",ThreadNum);
|
|
|
|
rc = NetUseEnum(
|
|
ServerName,
|
|
2,
|
|
&bufPtr,
|
|
RETURN_ALL,
|
|
&entriesRead,
|
|
&totalEntries,
|
|
&resumeHandle);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetUseEnum failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
printf("%d:NetUse done\n",ThreadNum);
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
|
|
Sleep(200);
|
|
//--------------------------
|
|
// SERVER: NetShareEnum
|
|
//--------------------------
|
|
printf("%d:NetShare\n",ThreadNum);
|
|
|
|
rc = NetShareEnum(
|
|
ServerName,
|
|
2,
|
|
&bufPtr,
|
|
RETURN_ALL,
|
|
&entriesRead,
|
|
&totalEntries,
|
|
&resumeHandle);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetShareEnum failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
printf("%d:NetShare done\n",ThreadNum);
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
|
|
//--------------------------------
|
|
// MESSENGER: NetMessageNameEnum
|
|
//--------------------------------
|
|
printf("%d:NetMessageName\n",ThreadNum);
|
|
rc = NetMessageNameEnum(
|
|
NULL,
|
|
1,
|
|
&bufPtr,
|
|
RETURN_ALL,
|
|
&entriesRead,
|
|
&totalEntries,
|
|
&resumeHandle);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetMessageNameEnum failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
printf("%d:NetMessageName done\n",ThreadNum);
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
|
|
|
|
//--------------------------------
|
|
// TIMESOURCE: NetRemoteTOD
|
|
//--------------------------------
|
|
printf("%d:NetRemoteTOD\n",ThreadNum);
|
|
rc = NetRemoteTOD (
|
|
ServerName,
|
|
&bufPtr);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetRemoteTOD failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
pTOD = (PTIME_OF_DAY_INFO)bufPtr;
|
|
printf("ThreadNum %d - - - Time %d:%d:%d, Day %d/%d/%d\n",
|
|
ThreadNum,
|
|
pTOD->tod_hours,
|
|
pTOD->tod_mins,
|
|
pTOD->tod_secs,
|
|
pTOD->tod_month,
|
|
pTOD->tod_day,
|
|
pTOD->tod_year);
|
|
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
Sleep(200);
|
|
//----------------------------------------
|
|
// SERVER: NetShareEnum (NULL ServerName)
|
|
//----------------------------------------
|
|
printf("%d:NetShare\n",ThreadNum);
|
|
|
|
rc = NetShareEnum(
|
|
NULL,
|
|
2,
|
|
&bufPtr,
|
|
RETURN_ALL,
|
|
&entriesRead,
|
|
&totalEntries,
|
|
&resumeHandle);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetShareEnum failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
printf("%d:NetShare done\n",ThreadNum);
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
|
|
//---------------------------------------------
|
|
// MESSENGER: NetMessageNameEnum
|
|
// This time it should re-use the bind handle.
|
|
//---------------------------------------------
|
|
printf("%d:NetMessageName\n",ThreadNum);
|
|
rc = NetMessageNameEnum(
|
|
NULL,
|
|
1,
|
|
&bufPtr,
|
|
RETURN_ALL,
|
|
&entriesRead,
|
|
&totalEntries,
|
|
&resumeHandle);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetMessageNameEnum failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
printf("%d:NetMessageName done\n",ThreadNum);
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
|
|
|
|
//--------------------------------
|
|
// TIMESOURCE: NetRemoteTOD
|
|
//--------------------------------
|
|
printf("%d:NetRemoteTOD\n",ThreadNum);
|
|
rc = NetRemoteTOD (
|
|
ServerName,
|
|
&bufPtr);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetRemoteTOD failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
pTOD = (PTIME_OF_DAY_INFO)bufPtr;
|
|
printf("ThreadNum %d - - - Time %d:%d:%d, Day %d/%d/%d\n",
|
|
ThreadNum,
|
|
pTOD->tod_hours,
|
|
pTOD->tod_mins,
|
|
pTOD->tod_secs,
|
|
pTOD->tod_month,
|
|
pTOD->tod_day,
|
|
pTOD->tod_year);
|
|
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
LoopCount--;
|
|
}
|
|
while (LoopCount > 0);
|
|
|
|
printf("Thread #%d Done\n",ThreadNum);
|
|
}
|
|
|
|
BOOL
|
|
ConvertToUnicode(
|
|
OUT LPWSTR *UnicodeOut,
|
|
IN LPSTR AnsiIn
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function translates an AnsiString into a Unicode string.
|
|
A new string buffer is created by this function. If the call to
|
|
this function is successful, the caller must take responsibility for
|
|
the unicode string buffer that was allocated by this function.
|
|
The allocated buffer should be free'd with a call to LocalFree.
|
|
|
|
NOTE: This function allocates memory for the Unicode String.
|
|
|
|
BUGBUG: This should be changed to return either
|
|
ERROR_NOT_ENOUGH_MEMORY or ERROR_INVALID_PARAMETER
|
|
|
|
Arguments:
|
|
|
|
AnsiIn - This is a pointer to an ansi string that is to be converted.
|
|
|
|
UnicodeOut - This is a pointer to a location where the pointer to the
|
|
unicode string is to be placed.
|
|
|
|
Return Value:
|
|
|
|
TRUE - The conversion was successful.
|
|
|
|
FALSE - The conversion was unsuccessful. In this case a buffer for
|
|
the unicode string was not allocated.
|
|
|
|
--*/
|
|
{
|
|
|
|
NTSTATUS ntStatus;
|
|
DWORD bufSize;
|
|
UNICODE_STRING unicodeString;
|
|
OEM_STRING ansiString;
|
|
|
|
//
|
|
// Allocate a buffer for the unicode string.
|
|
//
|
|
|
|
bufSize = (strlen(AnsiIn)+1) * sizeof(WCHAR);
|
|
|
|
*UnicodeOut = (LPWSTR)LocalAlloc(LMEM_ZEROINIT, bufSize);
|
|
|
|
if (*UnicodeOut == NULL) {
|
|
printf("ScConvertToUnicode:LocalAlloc Failure %ld\n",GetLastError());
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Initialize the string structures
|
|
//
|
|
NetpInitOemString( &ansiString, AnsiIn);
|
|
|
|
unicodeString.Buffer = *UnicodeOut;
|
|
unicodeString.MaximumLength = (USHORT)bufSize;
|
|
unicodeString.Length = 0;
|
|
|
|
//
|
|
// Call the conversion function.
|
|
//
|
|
ntStatus = RtlOemStringToUnicodeString (
|
|
&unicodeString, // Destination
|
|
&ansiString, // Source
|
|
FALSE); // Allocate the destination
|
|
|
|
if (!NT_SUCCESS(ntStatus)) {
|
|
|
|
printf("ScConvertToUnicode:RtlOemStringToUnicodeString Failure %lx\n",
|
|
ntStatus);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Fill in the pointer location with the unicode string buffer pointer.
|
|
//
|
|
*UnicodeOut = unicodeString.Buffer;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
SingleServiceTest(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
--*/
|
|
{
|
|
NET_API_STATUS rc;
|
|
DWORD entriesRead;
|
|
DWORD totalEntries;
|
|
DWORD resumeHandle;
|
|
LPBYTE bufPtr;
|
|
DWORD ThreadNum = 0;
|
|
DWORD i;
|
|
CHAR dump;
|
|
|
|
printf("This will loop 10 times - then exit\n");
|
|
for (i=0; i<10 ;i++ ) {
|
|
|
|
//---------------------------------------------
|
|
// MESSENGER: NetMessageNameEnum
|
|
//---------------------------------------------
|
|
printf("%d:NetMessageName\n",ThreadNum);
|
|
rc = NetMessageNameEnum(
|
|
NULL,
|
|
1,
|
|
&bufPtr,
|
|
RETURN_ALL,
|
|
&entriesRead,
|
|
&totalEntries,
|
|
&resumeHandle);
|
|
|
|
if (rc != NERR_Success) {
|
|
printf("NetMessageNameEnum failed 0x%ld\n", rc);
|
|
}
|
|
else {
|
|
printf("%d:NetMessageNameEnum success\n",ThreadNum);
|
|
NetApiBufferFree(bufPtr);
|
|
}
|
|
printf(" - (Repeat by pressing a key)");
|
|
|
|
dump = _getch();
|
|
printf("\r \n");
|
|
}
|
|
}
|