Source code of Windows XP (NT5)
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.

882 lines
24 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <tchar.h>
  4. #include "machines.h"
  5. #include "network.h"
  6. #include "server.h"
  7. #include "idw_dbg.h"
  8. /*++
  9. Filename : servers.c
  10. Description: This file will be for testing the servers access.
  11. Created by: Wally Ho
  12. History: Created on 03/29/99.
  13. 09.14.2001 Joe Holman Bug fixes for:
  14. 399178 Test Tools Triage joehol 2 chuckco STRESS: idwlog doesn't check for the validity of the handle coming back from CreateProcess
  15. 409338 Test Tools NtStress joehol 2 daviea STRESS:IdwLog - global file pointer becomes NULL and idwlog dies in crt call
  16. 09.19.2001 Joe Holman fixes for idwlog bugs 409338, 399178, and 352810
  17. 10.07.2001 Joe Holman Structure sometimes not filled in with Server name, so use global.
  18. Contains these functions:
  19. 1. IsServerOnline (IN LPTSTR szMachineName)
  20. 2. ServerOnlineThread (IN LPTSTR szServerFile)
  21. --*/
  22. BOOL
  23. IsServerOnline(IN LPINSTALL_DATA pId,
  24. IN LPTSTR szSpecifyShare)
  25. /*++
  26. Copyright (c) 2000, Microsoft.
  27. Author: Wally W. Ho (wallyho)
  28. Date: 03/29/99
  29. Routine Description:
  30. This will go through the list of servers specified in server.h
  31. It will return the first in it sees and reset the server share
  32. name in the LPINSTALL_DATA struct.
  33. Arguments:
  34. The LPINSTALL_DATA structure with the servername.
  35. Manual Server Name: NULL will give default behaviour.
  36. Return Value:
  37. TRUE for success.
  38. FALSE for no name.
  39. --*/
  40. {
  41. HANDLE hThrd[NUM_SERVERS];
  42. DWORD dw[NUM_SERVERS];
  43. DWORD dwExitCode;
  44. INT i;
  45. DWORD dwTimeOutInterval;
  46. BOOL b;
  47. Idwlog(TEXT("Entered IsServerOnLine().\n"));
  48. // This should allow for a
  49. // manually specified server.
  50. if (NULL != szSpecifyShare){
  51. _tcscpy(pId->szIdwlogServer,szSpecifyShare);
  52. Idwlog(TEXT("Returning IsServerOnLine() as FALSE (no name).\n"));
  53. return TRUE;
  54. }
  55. //make certain. The zeromemory we did should have set this.
  56. pId->bIsServerOnline = FALSE;
  57. // Initialize the Server.
  58. // Variable. Since we are using a single thread
  59. // to do a time out we don't care about mutexes and
  60. // sychronization.
  61. i = 0;
  62. #define TTEST
  63. #ifdef TTEST
  64. while ( i < NUM_SERVERS) {
  65. Idwlog(TEXT("IsServerOnLine - Trying connection to the server (i=%d,%d) %s.\n"), i, NUM_SERVERS, g_ServerBlock[i].szSvr);
  66. b = ServerOnlineThread ( (LPSERVERS)&g_ServerBlock[i] );
  67. if ( b ) {
  68. _tcscpy(pId->szIdwlogServer,g_ServerBlock[i].szSvr);
  69. pId->bIsServerOnline = TRUE;
  70. Idwlog(TEXT("Returning IsServerOnLine() TRUE due to online of: %s.\n"), pId->szIdwlogServer );
  71. return TRUE;
  72. }
  73. ++i; // try next server
  74. }
  75. Idwlog(TEXT("Returning IsServerOnLine() as FALSE (no name).\n"));
  76. return FALSE;
  77. #endif // TTEST
  78. while ( i < NUM_SERVERS) {
  79. hThrd[i] = NULL;
  80. Idwlog(TEXT("IsServerOnLine - Making connection to the server (i=%d,%d) %s.\n\n"), i, NUM_SERVERS, g_ServerBlock[i].szSvr);
  81. hThrd[i] = CreateThread(NULL,
  82. 0,
  83. (LPTHREAD_START_ROUTINE) ServerOnlineThread,
  84. (LPSERVERS)&g_ServerBlock[i],
  85. 0,
  86. &dw[i]);
  87. if ( hThrd[i] == NULL ) {
  88. Idwlog(TEXT("IsServerOnLine - ERROR CreateProcess: gle=%ld.\n"), GetLastError());
  89. ++i;
  90. continue;
  91. }
  92. // This is in milli seconds so the time out is secs.
  93. dwTimeOutInterval = TIME_TIMEOUT * 1000;
  94. g_ServerBlock[i].dwTimeOut = WaitForSingleObject (hThrd[i], dwTimeOutInterval);
  95. // This means the server was found and the timeout did not expire.
  96. if (g_ServerBlock[i].dwTimeOut != WAIT_TIMEOUT &&
  97. g_ServerBlock[i].bOnline == TRUE) {
  98. _tcscpy(pId->szIdwlogServer,g_ServerBlock[i].szSvr);
  99. pId->bIsServerOnline = TRUE;
  100. if (hThrd[i] != NULL) {
  101. CloseHandle (hThrd[i]);
  102. hThrd[i] = NULL;
  103. }
  104. Idwlog(TEXT("Returning IsServerOnLine() TRUE.\n"));
  105. return TRUE;
  106. } else {
  107. // We'll make sure the threads are killed so that we don't have a a race condition.
  108. Idwlog(TEXT("ServerOnlineTest: We could not connect to Server: %s\n"), /*pId->szIdwlogServer*/ g_ServerBlock[i].szSvr );
  109. // Exit the thread
  110. if (FALSE == GetExitCodeThread(hThrd[i],&dwExitCode))
  111. Idwlog(TEXT("IsServerOnLine - Failed to exit the server probe thread.\n"));
  112. else {
  113. // Don't terminate the thread yet...
  114. // TerminateThread(hThrd[i], dwExitCode);
  115. Idwlog(TEXT("IsServerOnLine - Timed out thread: %lu \n"), hThrd[i]);
  116. }
  117. CloseHandle (hThrd[i]);
  118. hThrd[i] = NULL;
  119. }
  120. i++;
  121. }
  122. Idwlog(TEXT("Returning IsServerOnLine() as FALSE (no name).\n"));
  123. return FALSE;
  124. }
  125. DWORD WINAPI
  126. ServerOnlineThread( IN LPSERVERS pServerBlock)
  127. /*++
  128. Copyright (c) 2000, Microsoft.
  129. Author: Wally W. Ho (wallyho)
  130. Date: 03/29/99
  131. Routine Description:
  132. This create a thread and then time it out to see if we can get to
  133. a server faster.
  134. Arguments:
  135. A server Block
  136. Return Value:
  137. TRUE for success.
  138. FALSE for failure.
  139. --*/
  140. {
  141. BOOL bCopy = FALSE;
  142. TCHAR szServerTestFile [MAX_PATH];
  143. TCHAR szRemoteName [MAX_PATH];
  144. HANDLE hServerTest;
  145. NETRESOURCE NetResource ;
  146. DWORD dwError;
  147. TCHAR szPassWord [ MAX_PATH ] = "\0";
  148. TCHAR szUserId [ MAX_PATH ] = "\0";
  149. LPTSTR p;
  150. Idwlog(TEXT("\n\nEntered ServerOnLineThread().\n\n"));
  151. // RemoteName is the server name alone without the share.
  152. // pServerBlock->szSvr comes in as \\idwlog\idwlogwhstl
  153. // make it idwlog only..
  154. _tcscpy(szRemoteName, pServerBlock->szSvr);
  155. if (szRemoteName){
  156. *_tcsrchr(szRemoteName,TEXT('\\')) = TEXT('\0');
  157. p = szRemoteName + 2;
  158. }
  159. // Let try to create the test file as the current logged-on user.
  160. // We don't expect every user to be able to connect in every domain.
  161. //
  162. _stprintf (szServerTestFile, TEXT("%s\\TST%lu.TST"), pServerBlock->szSvr, RandomMachineID());
  163. Idwlog(TEXT("ServerOnLineThread - Try to create test file with logged-on user: %s.\n"), szServerTestFile );
  164. hServerTest = CreateFile( szServerTestFile,
  165. GENERIC_WRITE,
  166. FILE_SHARE_WRITE | FILE_SHARE_READ,
  167. NULL,
  168. CREATE_ALWAYS,
  169. FILE_ATTRIBUTE_NORMAL| FILE_FLAG_WRITE_THROUGH,
  170. NULL );
  171. if ( hServerTest != INVALID_HANDLE_VALUE ){
  172. // Flush the buffers to make sure it all makes it to the drive.
  173. FlushFileBuffers(hServerTest);
  174. Idwlog(TEXT("ServerOnlineThread - Createfile success with specific user.\n"));
  175. // If succeeded delete the test file.
  176. CloseHandle( hServerTest );
  177. SetFileAttributes(szServerTestFile,FILE_ATTRIBUTE_NORMAL);
  178. DeleteFile( szServerTestFile );
  179. // Denote we have a server online.
  180. //
  181. pServerBlock->bOnline = TRUE;
  182. Idwlog(TEXT("ServerOnLineThread - returning TRUE.\n\n"));
  183. return TRUE;
  184. }
  185. else {
  186. Idwlog(TEXT("ServerOnLineThread - Warning Logged-on file creation test CreateFile FAILed gle = %ld.\n"), GetLastError());
  187. }
  188. // Setup the memory for the connection.
  189. //
  190. ZeroMemory( &NetResource, sizeof( NetResource ) );
  191. NetResource.dwType = RESOURCETYPE_DISK ;
  192. NetResource.lpLocalName = NULL;
  193. NetResource.lpRemoteName = szRemoteName;
  194. NetResource.lpProvider = NULL;
  195. Idwlog ( TEXT("ServerOnLineThread - szRemoteName=%s\n"), szRemoteName );
  196. // First, try to connect with the Guest Account
  197. _stprintf(szUserId , TEXT("%s\\Unknown"), p);
  198. _stprintf(szPassWord, TEXT(""));
  199. Idwlog(TEXT("ServerOnLineThread - First try with Guest.\n"));
  200. dwError = WNetAddConnection2( &NetResource, szPassWord, szUserId, 0 );
  201. if (NO_ERROR == dwError) {
  202. Idwlog(TEXT("ServerOnLineThread - WNetAddConnection2 authorized as guest on %s.\n"), pServerBlock->szSvr);
  203. // We connected, lets ALSO verify we can write a file.
  204. //
  205. _stprintf (szServerTestFile, TEXT("%s\\TST%lu.TST"), pServerBlock->szSvr, RandomMachineID());
  206. hServerTest = CreateFile( szServerTestFile,
  207. GENERIC_WRITE,
  208. FILE_SHARE_WRITE | FILE_SHARE_READ,
  209. NULL,
  210. CREATE_ALWAYS,
  211. FILE_ATTRIBUTE_NORMAL| FILE_FLAG_WRITE_THROUGH,
  212. NULL );
  213. if ( hServerTest != INVALID_HANDLE_VALUE ){
  214. // Flush the buffers to make sure it all makes it to the drive.
  215. FlushFileBuffers(hServerTest);
  216. Idwlog(TEXT("ServerOnlineThread - Createfile success with guest.\n"));
  217. // If succeeded delete the test file.
  218. CloseHandle( hServerTest );
  219. SetFileAttributes(szServerTestFile,FILE_ATTRIBUTE_NORMAL);
  220. DeleteFile( szServerTestFile );
  221. // Denote we have a server online.
  222. //
  223. pServerBlock->bOnline = TRUE;
  224. Idwlog(TEXT("ServerOnLineThread - returning TRUE.\n\n"));
  225. return TRUE;
  226. }
  227. else {
  228. Idwlog(TEXT("ServerOnLineThread - ERROR Guest file creation test CreateFile gle = %ld.\n"), GetLastError(), szServerTestFile );
  229. }
  230. }
  231. else {
  232. Idwlog(TEXT("ServerOnLineThread - ERROR Guest WNetAddConnection2 gle = %ld.\n"), dwError );
  233. }
  234. _stprintf(szUserId , TEXT("%s\\%s"), p, LOGSHARE_USER );
  235. _stprintf(szPassWord, TEXT("%s"), LOGSHARE_PW);
  236. Idwlog(TEXT("ServerOnLineThread - Second try with specific account.\n"));
  237. dwError = WNetAddConnection2( &NetResource, szPassWord, szUserId, 0 );
  238. if (NO_ERROR == dwError) {
  239. Idwlog(TEXT("ServerOnLineThread - WNetAddConnection2 authorized as specific user on %s.\n"), pServerBlock->szSvr);
  240. // We connected, lets ALSO verify we can write a file.
  241. //
  242. _stprintf (szServerTestFile, TEXT("%s\\TST%lu.TST"), pServerBlock->szSvr, RandomMachineID());
  243. hServerTest = CreateFile( szServerTestFile,
  244. GENERIC_WRITE,
  245. FILE_SHARE_WRITE | FILE_SHARE_READ,
  246. NULL,
  247. CREATE_ALWAYS,
  248. FILE_ATTRIBUTE_NORMAL| FILE_FLAG_WRITE_THROUGH,
  249. NULL );
  250. if ( hServerTest != INVALID_HANDLE_VALUE ){
  251. // Flush the buffers to make sure it all makes it to the drive.
  252. FlushFileBuffers(hServerTest);
  253. Idwlog(TEXT("ServerOnlineThread - Createfile success with specific user.\n"));
  254. // If succeeded delete the test file.
  255. CloseHandle( hServerTest );
  256. SetFileAttributes(szServerTestFile,FILE_ATTRIBUTE_NORMAL);
  257. DeleteFile( szServerTestFile );
  258. // Denote we have a server online.
  259. //
  260. pServerBlock->bOnline = TRUE;
  261. Idwlog(TEXT("ServerOnLineThread - returning TRUE.\n\n"));
  262. return TRUE;
  263. }
  264. else {
  265. Idwlog(TEXT("ServerOnLineThread - ERROR Specific user file creation test CreateFile gle = %ld, %s.\n"), GetLastError(), szServerTestFile );
  266. }
  267. }
  268. else {
  269. Idwlog(TEXT("ServerOnLineThread - ERROR Specific user WNetAddConnection2 gle = %ld.\n"), dwError );
  270. }
  271. // Must return that we couldn't authenticate and write test file in both cases.
  272. //
  273. Idwlog(TEXT("ServerOnLineThread - returning FALSE.\n\n"));
  274. return FALSE;
  275. }
  276. VOID
  277. WhatErrorMessage (IN DWORD dwError)
  278. /*++
  279. Copyright (c) 2000, Microsoft.
  280. Author: Wally W. Ho (wallyho)
  281. Date: 11/7/2000
  282. Routine Description:
  283. This gives a textual formatted message for any error code.
  284. Arguments:
  285. dword of the error code.
  286. Return Value:
  287. NONE
  288. --*/
  289. {
  290. HLOCAL hl = NULL;
  291. /***
  292. BOOL b = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  293. NULL, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  294. (LPTSTR) &hl, 0, NULL);
  295. if ( NULL != hl) {
  296. Idwlog(TEXT("Error %.5lu: %s"), dwError, (PCTSTR) LocalLock(hl));
  297. LocalFree(hl);
  298. }
  299. ***/
  300. DWORD dw = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  301. NULL, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  302. (LPTSTR) &hl, 0, NULL);
  303. if ( dw == 0 ) {
  304. Idwlog ( TEXT ( "ERROR - WhatErrorMessage's FormatMessage gle = %ld\n"), GetLastError () );
  305. }
  306. else {
  307. if ( NULL != hl) {
  308. // Show the error message when the string got translated.
  309. //
  310. Idwlog(TEXT("Error %.5lu: %s"), dwError, (PCTSTR) LocalLock(hl));
  311. LocalFree(hl);
  312. }
  313. else {
  314. // Show a generic text message with the error code when we can't translate it.
  315. //
  316. Idwlog(TEXT("An ERROR occurred, but we are having problems getting the message for it: %x (HEX)"), dwError );
  317. }
  318. }
  319. }
  320. /*
  321. BOOL IsMSI(VOID)
  322. ++
  323. Routine Description:
  324. This will check if its an MSI install.
  325. It will check for the running process
  326. and then check for the path.
  327. Arguments:
  328. Return Value:
  329. BOOL - True if link is good. False otherwise.
  330. --
  331. {
  332. DWORD numTasks = 0;
  333. TASK_LIST tlist[ MAX_PATH ];
  334. UINT i;
  335. BOOL bFound = FALSE;
  336. //
  337. // Get the Running Tasks.
  338. //
  339. numTasks = GetTaskList(tlist, MAX_PATH);
  340. //
  341. // If the MSI process exists log it as such.
  342. //
  343. for(i = 1; i <= numTasks; i++){
  344. if(_tcsstr(tlist[i].ProcessName, TEXT("msiexec.exe"))){
  345. MessageBox(NULL,tlist[i].ProcessName, TEXT("Caption"),MB_OK);
  346. lpCmdFrom.b_MsiInstall = TRUE;
  347. return FALSE;
  348. }else{
  349. lpCmdFrom.b_MsiInstall = TRUE;
  350. return TRUE;
  351. }
  352. }
  353. return TRUE;
  354. }
  355. */
  356. /*
  357. DWORD
  358. GetTaskList( PTASK_LIST pTask,
  359. DWORD dwNumTasks)
  360. ++
  361. // Borrowed with modifications from tlist a wesw invention.
  362. Routine Description:
  363. Provides an API for getting a list of tasks running at the time of the
  364. API call. This function uses the registry performance data to get the
  365. task list and is therefor straight WIN32 calls that anyone can call.
  366. Arguments:
  367. dwNumTasks - maximum number of tasks that the pTask array can hold
  368. Return Value:
  369. Number of tasks placed into the pTask array.
  370. --
  371. {
  372. DWORD rc;
  373. HKEY hKeyNames;
  374. DWORD dwType;
  375. DWORD dwSize;
  376. LPBYTE buf = NULL;
  377. CHAR szSubKey[1024];
  378. LANGID lid;
  379. LPSTR p;
  380. LPSTR p2;
  381. PPERF_DATA_BLOCK pPerf;
  382. PPERF_OBJECT_TYPE pObj;
  383. PPERF_INSTANCE_DEFINITION pInst;
  384. PPERF_COUNTER_BLOCK pCounter;
  385. PPERF_COUNTER_DEFINITION pCounterDef;
  386. DWORD i;
  387. DWORD dwProcessIdTitle;
  388. DWORD dwProcessIdCounter;
  389. CHAR szProcessName[MAX_PATH];
  390. DWORD dwLimit = dwNumTasks - 1;
  391. //
  392. // Look for the list of counters. Always use the neutral
  393. // English version, regardless of the local language. We
  394. // are looking for some particular keys, and we are always
  395. // going to do our looking in English. We are not going
  396. // to show the user the counter names, so there is no need
  397. // to go find the corresponding name in the local language.
  398. //
  399. lid = MAKELANGID( LANG_ENGLISH, SUBLANG_NEUTRAL );
  400. sprintf( szSubKey, "%s\\%03x", REGKEY_PERF, lid );
  401. rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  402. szSubKey,
  403. 0,
  404. KEY_READ,
  405. &hKeyNames
  406. );
  407. if (rc != ERROR_SUCCESS) {
  408. goto exit;
  409. }
  410. //
  411. // get the buffer size for the counter names
  412. //
  413. rc = RegQueryValueEx( hKeyNames,
  414. REGSUBKEY_COUNTERS,
  415. NULL,
  416. &dwType,
  417. NULL,
  418. &dwSize
  419. );
  420. if (rc != ERROR_SUCCESS) {
  421. goto exit;
  422. }
  423. //
  424. // allocate the counter names buffer
  425. //
  426. buf = (LPBYTE) malloc( dwSize );
  427. if (buf == NULL) {
  428. goto exit;
  429. }
  430. memset( buf, 0, dwSize );
  431. //
  432. // read the counter names from the registry
  433. //
  434. rc = RegQueryValueEx( hKeyNames,
  435. REGSUBKEY_COUNTERS,
  436. NULL,
  437. &dwType,
  438. buf,
  439. &dwSize
  440. );
  441. if (rc != ERROR_SUCCESS) {
  442. goto exit;
  443. }
  444. //
  445. // now loop thru the counter names looking for the following counters:
  446. //
  447. // 1. "Process" process name
  448. // 2. "ID Process" process id
  449. //
  450. // the buffer contains multiple null terminated strings and then
  451. // finally null terminated at the end. the strings are in pairs of
  452. // counter number and counter name.
  453. //
  454. p = buf;
  455. while (*p) {
  456. if (p > buf) {
  457. for( p2=p-2; isdigit(*p2); p2--) ;
  458. }
  459. if (_stricmp(p, PROCESS_COUNTER) == 0) {
  460. //
  461. // look backwards for the counter number
  462. //
  463. for( p2=p-2; isdigit(*p2); p2--) ;
  464. strcpy( szSubKey, p2+1 );
  465. }
  466. else
  467. if (_stricmp(p, PROCESSID_COUNTER) == 0) {
  468. //
  469. // look backwards for the counter number
  470. //
  471. for( p2=p-2; isdigit(*p2); p2--) ;
  472. dwProcessIdTitle = atol( p2+1 );
  473. }
  474. //
  475. // next string
  476. //
  477. p += (strlen(p) + 1);
  478. }
  479. //
  480. // free the counter names buffer
  481. //
  482. free( buf );
  483. //
  484. // allocate the initial buffer for the performance data
  485. //
  486. dwSize = INITIAL_SIZE;
  487. buf = malloc( dwSize );
  488. if (buf == NULL) {
  489. goto exit;
  490. }
  491. memset( buf, 0, dwSize );
  492. while (TRUE) {
  493. rc = RegQueryValueEx( HKEY_PERFORMANCE_DATA,
  494. szSubKey,
  495. NULL,
  496. &dwType,
  497. buf,
  498. &dwSize
  499. );
  500. pPerf = (PPERF_DATA_BLOCK) buf;
  501. //
  502. // check for success and valid perf data block signature
  503. //
  504. if ((rc == ERROR_SUCCESS) &&
  505. (dwSize > 0) &&
  506. (pPerf)->Signature[0] == (WCHAR)'P' &&
  507. (pPerf)->Signature[1] == (WCHAR)'E' &&
  508. (pPerf)->Signature[2] == (WCHAR)'R' &&
  509. (pPerf)->Signature[3] == (WCHAR)'F' ) {
  510. break;
  511. }
  512. //
  513. // if buffer is not big enough, reallocate and try again
  514. //
  515. if (rc == ERROR_MORE_DATA) {
  516. dwSize += EXTEND_SIZE;
  517. buf = realloc( buf, dwSize );
  518. memset( buf, 0, dwSize );
  519. }
  520. else {
  521. goto exit;
  522. }
  523. }
  524. //
  525. // set the perf_object_type pointer
  526. //
  527. pObj = (PPERF_OBJECT_TYPE) ((DWORD*)pPerf + pPerf->HeaderLength);
  528. //
  529. // loop thru the performance counter definition records looking
  530. // for the process id counter and then save its offset
  531. //
  532. pCounterDef = (PPERF_COUNTER_DEFINITION) ((DWORD *)pObj + pObj->HeaderLength);
  533. for (i=0; i<(DWORD)pObj->NumCounters; i++) {
  534. if (pCounterDef->CounterNameTitleIndex == dwProcessIdTitle) {
  535. dwProcessIdCounter = pCounterDef->CounterOffset;
  536. break;
  537. }
  538. pCounterDef++;
  539. }
  540. dwNumTasks = min( dwLimit, (DWORD)pObj->NumInstances );
  541. pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD*)pObj + pObj->DefinitionLength);
  542. //
  543. // loop thru the performance instance data extracting each process name
  544. // and process id
  545. //
  546. for (i=0; i<dwNumTasks; i++) {
  547. //
  548. // pointer to the process name
  549. //
  550. p = (LPSTR) ((DWORD*)pInst + pInst->NameOffset);
  551. //
  552. // convert it to ascii
  553. //
  554. rc = WideCharToMultiByte( CP_ACP,
  555. 0,
  556. (LPCWSTR)p,
  557. -1,
  558. szProcessName,
  559. sizeof(szProcessName),
  560. NULL,
  561. NULL
  562. );
  563. if (!rc) {
  564. //
  565. // if we cant convert the string then use a bogus value
  566. //
  567. strcpy( pTask->ProcessName, UNKNOWN_TASK );
  568. }
  569. if (strlen(szProcessName)+4 <= sizeof(pTask->ProcessName)) {
  570. strcpy( pTask->ProcessName, szProcessName );
  571. strcat( pTask->ProcessName, ".exe" );
  572. }
  573. //
  574. // get the process id
  575. //
  576. pCounter = (PPERF_COUNTER_BLOCK) ((DWORD*)pInst + pInst->ByteLength);
  577. pTask->flags = 0;
  578. pTask->dwProcessId = *((LPDWORD) ((DWORD*)pCounter + dwProcessIdCounter));
  579. if (pTask->dwProcessId == 0) {
  580. pTask->dwProcessId = (DWORD)-2;
  581. }
  582. //
  583. // next process
  584. //
  585. pTask++;
  586. pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD*)pCounter + pCounter->ByteLength);
  587. }
  588. exit:
  589. if (buf) {
  590. free( buf );
  591. }
  592. RegCloseKey( hKeyNames );
  593. RegCloseKey( HKEY_PERFORMANCE_DATA );
  594. //
  595. // W.Ho added a minus 1 to get it to reflect the
  596. // tasks properly.
  597. //
  598. return dwNumTasks -1;
  599. }
  600. */
  601. /*
  602. typedef struct _SERVERS {
  603. TCHAR szSvr [ MAX_PATH ];
  604. BOOL bCFTest;
  605. DWORD dwNetStatus;
  606. } *LPSERVERS, SERVERS;
  607. typedef struct _ERRMSG {
  608. TCHAR szMsg[ MAX_PATH ];
  609. DWORD dwErr;
  610. } *LPERRMSG, ERRMSG;
  611. BOOL
  612. IsServerOnline(VOID)
  613. /*++
  614. Routine Description:
  615. Arguments:
  616. Return Value:
  617. NONE.
  618. --
  619. {
  620. #define NUM_SERVERS 6
  621. INT i;
  622. TCHAR sz[ MAX_PATH ];
  623. ERRMSG e[12] = {
  624. {TEXT("Access is denied."), ERROR_ACCESS_DENIED},
  625. {TEXT("The device specified in the lpLocalName parameter is already connected."), ERROR_ALREADY_ASSIGNED },
  626. {TEXT("The device type and the resource type do not match."), ERROR_BAD_DEV_TYPE},
  627. {TEXT("The value specified in lpLocalName is invalid."), ERROR_BAD_DEVICE},
  628. {TEXT("The value specified in the lpRemoteName parameter is not valid or cannot be located."), ERROR_BAD_NET_NAME},
  629. {TEXT("The user profile is in an incorrect format."), ERROR_BAD_PROFILE},
  630. {TEXT("The system is unable to open the user profile to process persistent connections."),ERROR_CANNOT_OPEN_PROFILE },
  631. {TEXT("An entry for the device specified in lpLocalName is already in the user profile."), ERROR_DEVICE_ALREADY_REMEMBERED},
  632. {TEXT("A network-specific error occurred. To get a description of the error, use the WNetGetLastError function."), ERROR_EXTENDED_ERROR},
  633. {TEXT("The specified password is invalid."), ERROR_INVALID_PASSWORD},
  634. {TEXT("The operation cannot be performed because either a network component is not started or the specified name cannot be used."),ERROR_NO_NET_OR_BAD_PATH },
  635. {TEXT("The network is not present."),ERROR_NO_NETWORK}
  636. };
  637. SERVERS s[NUM_SERVERS] ={
  638. {TEXT("\\\\donkeykongjr\\public"), -1, -1},
  639. {TEXT("\\\\popcorn\\public"), -1, -1},
  640. {TEXT("\\\\NotExists\\idwlog"), -1, -1},
  641. {TEXT("\\\\Paddy\\idwlog"), -1, -1},
  642. {TEXT("\\\\Bear\\idwlog"), -1, -1},
  643. {TEXT("\\\\JustTesting\\idwlog"), -1, -1}
  644. };
  645. for (i = 0; i < 12; i++) {
  646. _tprintf(TEXT("Error %s %lu\n"),e[i].szMsg, e[i].dwErr);
  647. }
  648. for (i = 0; i < NUM_SERVERS; i++){
  649. s[i].dwNetStatus = WNetAddConnection(TEXT("donkeykongjr\\public\0"),NULL,NULL);
  650. _stprintf(sz,TEXT("%s%s"),s[i].szSvr,TEXT("\\test") );
  651. s[i].bCFTest = CopyFile(TEXT("c:\\test"),sz,FALSE);
  652. _tprintf(TEXT("Did this work for %s %s %lu\n"),
  653. sz,
  654. s[i].bCFTest? TEXT("WORKED"): TEXT("FAILED"),
  655. s[i].dwNetStatus
  656. );
  657. }
  658. return FALSE;
  659. }
  660. */