/*++ Copyright (c) 1991 Microsoft Corporation Module Name: wstest.c Abstract: Test program for the NetWksta and NetUse APIs. Run this test after starting the Workstation service. Author: Rita Wong (ritaw) 12-Mar-1991 Revision History: --*/ #include #include #include #include #include #include #include #include // Win32 type definitions #include // Win32 base API prototypes #include // LAN Man definitions #include // NetpDbgDisplayWksta() #include #include #ifdef UNICODE #define FORMAT_STR "ws " #else #define FORMAT_STR "s " #endif #define CHANGE_HEURISTICS \ for (i = 0, ptr = &(redir->wki502_use_opportunistic_locking); i < 14; \ i++, ptr++) { \ if (*ptr) { \ *ptr = FALSE; \ } \ else { \ *ptr = TRUE; \ } \ } CHAR WorkBuffer[(DEVLEN + RMLEN + PWLEN + UNLEN + DNLEN + 5) * sizeof(TCHAR) + sizeof(PUSE_INFO_2)]; LPWSTR TargetMachine = NULL; VOID WsTestWkstaInfo( VOID ); VOID WsTestWkstaTransportEnum( VOID ); VOID WsTestUse( VOID ); VOID TestUseAdd( IN LPBYTE Buffer, IN DWORD ExpectedStatus ); VOID TestUseDel( IN LPTSTR UseName, IN DWORD ForceLevel, IN DWORD ExpectedStatus ); VOID TestUseEnum( DWORD PreferedMaximumLength, IN OUT LPDWORD ResumeHandle OPTIONAL ); VOID TestUseGetInfo( LPTSTR UseName, DWORD ExpectedStatus ); VOID PrintUseInfo1( PUSE_INFO_1 UseInfo ); VOID PrintUseInfo2( PUSE_INFO_2 UseInfo ); VOID __cdecl main( int argc, char *argv[] ) { if (argc > 1) { if (argc == 3) { TargetMachine = NetpAllocWStrFromStr(argv[2]); if (TargetMachine != NULL) { printf("New Target is %ws\n", TargetMachine); } } WsTestWkstaInfo(); WsTestWkstaTransportEnum(); if (TargetMachine != NULL) { NetApiBufferFree(TargetMachine); } } WsTestUse(); } VOID WsTestWkstaInfo( VOID ) { NET_API_STATUS status; PWKSTA_INFO_502 redir; PWKSTA_INFO_102 systeminfo102; PWKSTA_INFO_100 systeminfo100; PWKSTA_INFO_101 systeminfo101; PWKSTA_USER_INFO_0 UserInfo0; PWKSTA_USER_INFO_1 UserInfo; DWORD ErrorParameter; DWORD i = 0; BOOL *ptr = NULL; DWORD ResumeHandle = 0; DWORD EntriesRead; DWORD TotalEntries; printf("In wstest.exe\n\n"); status = NetWkstaGetInfo( TargetMachine, 502, (LPBYTE *) &redir ); printf("NetWkstaGetInfo Test:status=%lu\n", status); if (status != NERR_Success) { goto TrySomethingElse; } redir->wki502_char_wait++; redir->wki502_maximum_collection_count++; redir->wki502_collection_time++; redir->wki502_keep_conn++; redir->wki502_siz_char_buf++; redir->wki502_max_cmds++; // Not settable: should be ignored redir->wki502_sess_timeout++; redir->wki502_lock_quota++; redir->wki502_lock_increment++; redir->wki502_lock_maximum++; redir->wki502_pipe_increment++; redir->wki502_pipe_maximum++; redir->wki502_cache_file_timeout++; CHANGE_HEURISTICS; status = NetWkstaSetInfo( TargetMachine, 502, (LPBYTE) redir, &ErrorParameter ); printf("NetWkstaSetInfo Test:status=%lu\n", status); // // Free the get info buffer. We are getting another buffer from the // next get. // NetApiBufferFree(redir); if (status != NERR_Success) { if (status == ERROR_INVALID_PARAMETER) { printf( "NetWkstaSetInfo parameter %lu causes ERROR_INVALID_PARAMETER\n", ErrorParameter ); } goto TrySomethingElse; } status = NetWkstaGetInfo( TargetMachine, 502, (LPBYTE *) &redir ); printf("NetWkstaGetInfo again: status=%lu\n", status); if (status != NERR_Success) { goto TrySomethingElse; } printf("\nAfter NetWkstaSetInfo, all values should be 1 extra" " maxcmds\n"); redir->wki502_char_wait--; redir->wki502_collection_time--; redir->wki502_maximum_collection_count--; redir->wki502_keep_conn--; redir->wki502_siz_char_buf--; //redir->wki502_max_cmds--; // Not settable redir->wki502_sess_timeout--; redir->wki502_lock_quota--; redir->wki502_lock_increment--; redir->wki502_lock_maximum--; redir->wki502_pipe_increment--; redir->wki502_pipe_maximum--; redir->wki502_cache_file_timeout--; CHANGE_HEURISTICS; status = NetWkstaSetInfo( TargetMachine, 502, (LPBYTE) redir, NULL ); NetApiBufferFree(redir); printf("NetWkstaGetInfo to reset to original values: status=%lu\n", status); TrySomethingElse: // // Get system info 102 // status = NetWkstaGetInfo( TargetMachine, 102, (LPBYTE *) &systeminfo102 ); if (status == NERR_Success) { NetApiBufferFree(systeminfo102); } else { printf("NetWkstaGetInfo level 102: FAILED %lu\n", status); } // // Get system info 100 // status = NetWkstaGetInfo( TargetMachine, 100, (LPBYTE *) &systeminfo100 ); if (status == NERR_Success) { NetApiBufferFree(systeminfo100); } else { printf("NetWkstaGetInfo level 100: FAILED %lu\n", status); } // // Get system info 101 // status = NetWkstaGetInfo( TargetMachine, 101, (LPBYTE *) &systeminfo101 ); if (status == NERR_Success) { NetApiBufferFree(systeminfo101); } else { printf("NetWkstaGetInfo level 101: FAILED %lu\n", status); } // // Get user info level 1 // status = NetWkstaUserGetInfo( NULL, 1, (LPBYTE *) &UserInfo ); if (status == NERR_Success) { printf("NetWkstaUserGetInfo level 1:\n" "username=" FORMAT_LPTSTR "\nlogon domain=" FORMAT_LPTSTR "\nother domains=" FORMAT_LPTSTR "\nlogon server=" FORMAT_LPTSTR "\n", UserInfo->wkui1_username, UserInfo->wkui1_logon_domain, UserInfo->wkui1_oth_domains, UserInfo->wkui1_logon_server ); NetApiBufferFree(UserInfo); } else { printf("NetWkstaUserGetInfo level 1: FAILED %lu", status); } // // Get user info level 0 // status = NetWkstaUserGetInfo( NULL, 0, (LPBYTE *) &UserInfo0 ); if (status == NERR_Success) { printf("NetWkstaUserGetInfo level 0:\nusername=" FORMAT_LPTSTR "\n", UserInfo0->wkui0_username ); NetApiBufferFree(UserInfo0); } else { printf("NetWkstaUserGetInfo level 0: FAILED %lu", status); } status = NetWkstaUserEnum ( TargetMachine, 1, (LPBYTE *) &UserInfo, MAXULONG, &EntriesRead, &TotalEntries, &ResumeHandle ); if (status == NERR_Success) { PWKSTA_USER_INFO_1 TmpPtr = UserInfo; printf("NetWkstaUserEnum level 1: EntriesRead=%lu, TotalEntries=%lu\n", EntriesRead, TotalEntries); for (i = 0; i < EntriesRead; i++, UserInfo++) { printf(" username=" FORMAT_LPTSTR "\nlogon domain=" FORMAT_LPTSTR "\nother domains=" FORMAT_LPTSTR "\nlogon server=" FORMAT_LPTSTR "\n", UserInfo->wkui1_username, UserInfo->wkui1_logon_domain, UserInfo->wkui1_oth_domains, UserInfo->wkui1_logon_server ); } NetApiBufferFree(TmpPtr); } else { printf("NetWkstaUserEnum level 1: FAILED %lu", status); } } VOID WsTestWkstaTransportEnum( VOID ) { NET_API_STATUS status; LPBYTE Buffer; DWORD EntriesRead, TotalEntries, ResumeHandle = 0; status = NetWkstaTransportEnum( NULL, 0, &Buffer, MAXULONG, &EntriesRead, &TotalEntries, &ResumeHandle ); printf("NetWkstaTransportEnum Test:status=%lu\n", status); if (status == NERR_Success) { printf(" EntriesRead=%lu, TotalEntries=%lu\n", EntriesRead, TotalEntries); NetApiBufferFree(Buffer); } } VOID WsTestUse( VOID ) { PUSE_INFO_2 UseInfo = (PUSE_INFO_2) WorkBuffer; DWORD ResumeHandle = 0; DWORD i; LPTSTR PasswordSavePtr; LPTSTR UserNameSavePtr; LPTSTR DomainNameSavePtr; // // Initialize string pointers. Local device points to the bottom // of Info 2 structure; Shared resource points to the middle of // buffer (away from everything so there's no chance of overwriting // or being overwritten. // UseInfo->ui2_local = (LPTSTR) &WorkBuffer[sizeof(USE_INFO_2)]; UseInfo->ui2_remote = (LPTSTR) ((DWORD) UseInfo->ui2_local) + (DEVLEN + 1) * sizeof(TCHAR); UseInfo->ui2_password = NULL; PasswordSavePtr = (LPTSTR) ((DWORD) UseInfo->ui2_remote) + (RMLEN + 1) * sizeof(TCHAR); UseInfo->ui2_username = NULL; UserNameSavePtr = (LPTSTR) ((DWORD) PasswordSavePtr) + (PWLEN + 1) * sizeof(TCHAR); UseInfo->ui2_domainname = NULL; DomainNameSavePtr = (LPTSTR) ((DWORD) UserNameSavePtr) + (DNLEN + 1) * sizeof(TCHAR); UseInfo->ui2_asg_type = USE_DISKDEV; // // Test with explicit username and password // UseInfo->ui2_username = UserNameSavePtr; UseInfo->ui2_password = PasswordSavePtr; UseInfo->ui2_domainname = DomainNameSavePtr; STRCPY(UseInfo->ui2_username, TEXT("NTBUILD")); STRCPY(UseInfo->ui2_password, TEXT("NTBUILD")); STRCPY(UseInfo->ui2_domainname, TEXT("NtWins")); STRCPY(UseInfo->ui2_local, TEXT("k:")); STRCPY(UseInfo->ui2_remote, TEXT("\\\\kernel\\razzle2")); TestUseAdd(WorkBuffer, NERR_Success); TestUseGetInfo(TEXT("K:"), NERR_Success); UseInfo->ui2_password = NULL; UseInfo->ui2_domainname = NULL; // // Connect to \\kernel\razzle2 again with only the username // STRCPY(UseInfo->ui2_local, TEXT("j:")); TestUseAdd(WorkBuffer, NERR_Success); // // Add 5 \\ritaw2\public // UseInfo->ui2_username = NULL; STRCPY(UseInfo->ui2_local, TEXT("")); STRCPY(UseInfo->ui2_remote, TEXT("\\\\ritaw2\\public")); for (i = 0; i < 5; i++) { TestUseAdd(WorkBuffer, NERR_Success); } TestUseDel( TEXT("j:"), USE_LOTS_OF_FORCE, NERR_Success ); TestUseDel( TEXT("k:"), USE_LOTS_OF_FORCE, NERR_Success ); // // Add p: \\ritaw2\public // STRCPY(UseInfo->ui2_local, TEXT("p:")); TestUseAdd(WorkBuffer, NERR_Success); // // Add U: \\ritaw2\public // STRCPY(UseInfo->ui2_local, TEXT("U:")); TestUseAdd(WorkBuffer, NERR_Success); // // Add s: \\ritaw2\testdir // STRCPY(UseInfo->ui2_local, TEXT("s:")); STRCPY(UseInfo->ui2_remote, TEXT("\\\\ritaw2\\testdir")); TestUseAdd(WorkBuffer, NERR_Success); TestUseAdd(WorkBuffer, ERROR_ALREADY_ASSIGNED); TestUseGetInfo(TEXT("\\\\ritaw2\\testdir"), NERR_UseNotFound); // // Add 3 \\ritaw2\testdir // STRCPY(UseInfo->ui2_local, TEXT("")); for (i = 0; i < 3; i++) { TestUseAdd(WorkBuffer, NERR_Success); } // // Create implicit connections // system("ls \\\\ritaw2\\pub2"); system("ls \\\\ritaw2\\tmp"); // // Delete implicit connection \\ritaw2\tmp USE_NOFORCE. // TestUseDel( TEXT("\\\\ritaw2\\tmp"), USE_NOFORCE, NERR_Success ); // // Enumerate all connections // TestUseEnum(MAXULONG, NULL); TestUseEnum(150, &ResumeHandle); TestUseEnum(100, &ResumeHandle); for (i = 0; i < 3; i++) { TestUseEnum(50, &ResumeHandle); } TestUseEnum(150, NULL); // // Get info // TestUseGetInfo(TEXT("\\\\ritaw2\\public"), NERR_Success); TestUseGetInfo(TEXT("p:"), NERR_Success); TestUseGetInfo(TEXT("\\\\ritaw2\\Z"), NERR_UseNotFound); TestUseGetInfo(TEXT("\\\\ritaw2\\Testdir"), NERR_Success); TestUseGetInfo(TEXT("S:"), NERR_Success); // // Delete \\ritaw2\public USE_NOFORCE. Decrements usecount from 5 to 4. // TestUseDel( TEXT("\\\\ritaw2\\public"), USE_NOFORCE, NERR_Success ); // // Delete \\ritaw2\public USE_FORCE. This should delete all 4 usecounts. // TestUseDel( TEXT("\\\\ritaw2\\public"), USE_FORCE, NERR_Success ); TestUseDel( TEXT("\\\\ritaw2\\public"), USE_FORCE, NERR_UseNotFound ); // // Delete s: USE_FORCE // TestUseDel( TEXT("s:"), USE_LOTS_OF_FORCE, NERR_Success ); // // Add s: \\ritaw2\z // STRCPY(UseInfo->ui2_local, TEXT("s:")); STRCPY(UseInfo->ui2_remote, TEXT("\\\\ritaw2\\z")); TestUseAdd(WorkBuffer, NERR_Success); // // Delete p: USE_NOFORCE. Second time should get NERR_UseNotFound. // TestUseDel( TEXT("p:"), USE_LOTS_OF_FORCE, NERR_Success ); TestUseDel( TEXT("p:"), USE_LOTS_OF_FORCE, NERR_UseNotFound ); // // Delete \\ritaw2\testdir USE_NOFORCE. 4th time should be // NERR_UseNotFound. // for (i = 0; i < 3; i++) { TestUseDel( TEXT("\\\\ritaw2\\testdir"), USE_NOFORCE, NERR_Success ); } TestUseDel( TEXT("\\\\ritaw2\\testdir"), USE_NOFORCE, NERR_UseNotFound ); // // Add prn: \\ritaw2\prn // UseInfo->ui2_asg_type = USE_SPOOLDEV; STRCPY(UseInfo->ui2_local, TEXT("prn")); STRCPY(UseInfo->ui2_remote, TEXT("\\\\prt21088\\laserii")); TestUseAdd(WorkBuffer, NERR_Success); // // Add lpt1: \\ritaw2\laser, should get ERROR_ALREADY_ASSIGNED because prn: // is converted to lpt1. // STRCPY(UseInfo->ui2_local, TEXT("lpt1:")); STRCPY(UseInfo->ui2_remote, TEXT("\\\\prt21088\\laserii")); TestUseAdd(WorkBuffer, ERROR_ALREADY_ASSIGNED); // // Delete LPT1 USE_LOTS_OF_FORCE, should succeed // TestUseDel( TEXT("prn:"), USE_LOTS_OF_FORCE, NERR_Success ); // // Bad device type // STRCPY(UseInfo->ui2_local, TEXT("")); STRCPY(UseInfo->ui2_remote, TEXT("\\\\ritaw2\\public")); UseInfo->ui2_asg_type = 12345678; TestUseAdd(WorkBuffer, NERR_BadAsgType); TestUseDel( TEXT("S:"), USE_LOTS_OF_FORCE, NERR_Success ); TestUseDel( TEXT("U:"), USE_LOTS_OF_FORCE, NERR_Success ); } VOID TestUseAdd( IN LPBYTE Buffer, IN DWORD ExpectedStatus ) { NET_API_STATUS status; DWORD ErrorParameter; status = NetUseAdd( NULL, 2, Buffer, &ErrorParameter ); printf("NetUseAdd %-5" FORMAT_STR "%-25" FORMAT_STR, ((PUSE_INFO_2) Buffer)->ui2_local, ((PUSE_INFO_2) Buffer)->ui2_remote); if (status != ExpectedStatus) { printf("FAILED: Got %lu, expected %lu\n", status, ExpectedStatus); } else { printf("OK: Got expected status %lu\n", status); } if (status == ERROR_INVALID_PARAMETER) { printf("NetUseAdd parameter %lu is cause of ERROR_INVALID_PARAMETER\n", ErrorParameter); } } VOID TestUseDel( IN LPTSTR UseName, IN DWORD ForceLevel, IN DWORD ExpectedStatus ) { NET_API_STATUS status; PWCHAR Force[3] = { L"NOFORCE", L"FORCE", L"LOTS_OF_FORCE" }; printf("NetUseDel %-17" FORMAT_STR "%-13" FORMAT_STR, UseName, Force[ForceLevel]); status = NetUseDel( NULL, UseName, ForceLevel ); if (status != ExpectedStatus) { printf("FAILED: Got %lu, expected %lu\n", status, ExpectedStatus); } else { printf("OK: Got expected status %lu\n", status); } } VOID TestUseGetInfo( LPTSTR UseName, DWORD ExpectedStatus ) { NET_API_STATUS status; PUSE_INFO_2 UseInfo; printf("NetUseGetInfo %-27" FORMAT_STR, UseName); status = NetUseGetInfo( NULL, UseName, 2, (LPBYTE *) &UseInfo ); if (status != ExpectedStatus) { printf("FAILED: Got %lu, expected %lu\n", status, ExpectedStatus); } else { printf("OK: Got expected status %lu\n", status); } if (status == NERR_Success) { PrintUseInfo2(UseInfo); NetApiBufferFree(UseInfo); } } VOID TestUseEnum( IN DWORD PreferedMaximumLength, IN OUT LPDWORD ResumeHandle OPTIONAL ) { DWORD i; NET_API_STATUS status; DWORD EntriesRead, TotalEntries; PUSE_INFO_1 UseInfo, saveptr; if (ARGUMENT_PRESENT(ResumeHandle)) { printf("\nInput ResumeHandle=x%08lx\n", *ResumeHandle); } status = NetUseEnum( NULL, 1, (LPBYTE *) &UseInfo, PreferedMaximumLength, &EntriesRead, &TotalEntries, ResumeHandle ); saveptr = UseInfo; if (status != NERR_Success && status != ERROR_MORE_DATA) { printf("NetUseEnum FAILED %lu\n", status); } else { printf("Return code from NetUseEnum %lu\n", status); printf("EntriesRead=%lu, TotalEntries=%lu\n", EntriesRead, TotalEntries); if (ARGUMENT_PRESENT(ResumeHandle)) { printf("Output ResumeHandle=x%08lx\n", *ResumeHandle); } for (i = 0; i < EntriesRead; i++, UseInfo++) { PrintUseInfo1(UseInfo); } // // Free buffer allocated for us. // NetApiBufferFree(saveptr); } } VOID PrintUseInfo1( PUSE_INFO_1 UseInfo ) { switch(UseInfo->ui1_status) { case USE_OK: printf("OK "); break; case USE_PAUSED: printf("Paused "); break; case USE_SESSLOST: printf("Disconnected "); break; case USE_NETERR: printf("Net error "); break; case USE_CONN: printf("Connecting "); break; case USE_RECONN: printf("Reconnecting "); break; default: printf("Unknown "); } printf(" %-7" FORMAT_STR "%-25" FORMAT_STR, UseInfo->ui1_local, UseInfo->ui1_remote); printf("usecount=%lu, refcount=%lu\n", UseInfo->ui1_usecount, UseInfo->ui1_refcount); } VOID PrintUseInfo2( PUSE_INFO_2 UseInfo ) { switch(UseInfo->ui2_status) { case USE_OK: printf("OK "); break; case USE_PAUSED: printf("Paused "); break; case USE_SESSLOST: printf("Disconnected "); break; case USE_NETERR: printf("Net error "); break; case USE_CONN: printf("Connecting "); break; case USE_RECONN: printf("Reconnecting "); break; default: printf("Unknown "); } printf(" %-7" FORMAT_STR "%-" FORMAT_STR, UseInfo->ui2_local, UseInfo->ui2_remote); printf("\n %-25" FORMAT_STR "%-" FORMAT_STR, UseInfo->ui2_username, UseInfo->ui2_domainname); printf("\n usecount=%02lu, refcount=%02lu\n", UseInfo->ui2_usecount, UseInfo->ui2_refcount); }