Leaked source code of windows server 2003
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.

1258 lines
35 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <resapi.h>
  4. #include <clusapi.h>
  5. #include <clusstor.h>
  6. #define MAX_NAME_SIZE MAX_PATH
  7. #define START_BUFFER_SIZE 2048
  8. #define PHYSICAL_DISK_WSTR L"Physical Disk"
  9. //
  10. // Always specify the fully qualified path name to the DLL.
  11. //
  12. #define MODULE_NAME_VALID "%SystemRoot%\\cluster\\passthru.dll"
  13. #define PROC_EXCEPTION "TestDllCauseException"
  14. #define PROC_GET_BOOT_SECTOR "TestDllGetBootSector"
  15. #define PROC_CONTEXT_AS_ERROR "TestDllReturnContextAsError"
  16. #define PROC_NOT_ENOUGH_PARMS "TestDllNotEnoughParms"
  17. #define PROC_TOO_MANY_PARMS "TestDllTooManyParms"
  18. // 6118L ERROR_NO_BROWSER_SERVERS_FOUND
  19. #define CONTEXT_ERROR_STR "6118"
  20. #define MODULE_NAME_INVALID "NoSuchModule.dll"
  21. #define PROC_NAME_INVALID "NoSuchProc"
  22. #define MAX_OUT_BUFFER_SIZE 2048
  23. #define BOOT_SECTOR_SIZE 512
  24. // Specfic ASR tests
  25. #define ASRP_GET_LOCAL_DISK_INFO "AsrpGetLocalDiskInfo"
  26. #define ASRP_GET_LOCAL_VOLUME_INFO "AsrpGetLocalVolumeInfo"
  27. #define SYSSETUP_DLL "syssetup.dll"
  28. //
  29. // Use this to verify the parse routine.
  30. //
  31. // #define TEST_PARSE_ROUTINE 11
  32. typedef struct _RESOURCE_STATE {
  33. CLUSTER_RESOURCE_STATE State;
  34. LPWSTR ResNodeName;
  35. LPWSTR ResGroupName;
  36. } RESOURCE_STATE, *PRESOURCE_STATE;
  37. VOID
  38. DumpBuffer(
  39. IN PUCHAR Buffer,
  40. IN DWORD ByteCount
  41. );
  42. DWORD
  43. GetResourceInfo(
  44. RESOURCE_HANDLE hOriginal,
  45. RESOURCE_HANDLE hResource,
  46. PVOID lpParams
  47. );
  48. DWORD
  49. GetResourceState(
  50. HRESOURCE Resource,
  51. PRESOURCE_STATE ResState
  52. );
  53. DWORD
  54. GetSignature(
  55. RESOURCE_HANDLE hResource,
  56. DWORD *dwSignature
  57. );
  58. BOOLEAN
  59. GetSignatureFromDiskInfo(
  60. PBYTE DiskInfo,
  61. DWORD *Signature,
  62. DWORD DiskInfoSize
  63. );
  64. LPBYTE
  65. ParseDiskInfo(
  66. PBYTE DiskInfo,
  67. DWORD DiskInfoSize,
  68. DWORD SyntaxValue
  69. );
  70. VOID
  71. PrintError(
  72. DWORD ErrorCode
  73. );
  74. DWORD
  75. ResourceCallback(
  76. RESOURCE_HANDLE hOriginal,
  77. RESOURCE_HANDLE hResource,
  78. PVOID lpParams
  79. );
  80. CLUSTER_RESOURCE_STATE
  81. WINAPI
  82. WrapGetClusterResourceState(
  83. IN HRESOURCE hResource,
  84. OUT OPTIONAL LPWSTR * ppwszNodeName,
  85. OUT OPTIONAL LPWSTR * ppwszGroupName
  86. );
  87. DWORD
  88. WrapClusterResourceControl(
  89. RESOURCE_HANDLE hResource,
  90. DWORD dwControlCode,
  91. LPVOID *ppwszOutBuffer,
  92. DWORD *dwBytesReturned
  93. );
  94. DWORD
  95. __cdecl
  96. main(
  97. int argc,
  98. char *argv[]
  99. )
  100. {
  101. DWORD dwStatus = NO_ERROR;
  102. //
  103. // No parameter validation...
  104. //
  105. dwStatus = ResUtilEnumResources( NULL,
  106. PHYSICAL_DISK_WSTR,
  107. ResourceCallback,
  108. NULL
  109. );
  110. if ( NO_ERROR != dwStatus ) {
  111. printf("\nResUtilEnumResources returns: %d \n", dwStatus);
  112. PrintError(dwStatus);
  113. }
  114. return dwStatus;
  115. } // main
  116. DWORD
  117. ResourceCallback(
  118. RESOURCE_HANDLE hOriginal,
  119. RESOURCE_HANDLE hResource,
  120. PVOID lpParams
  121. )
  122. {
  123. PCHAR outBuffer = NULL;
  124. DWORD dwStatus = NO_ERROR;
  125. DWORD inBufferSize = sizeof(DISK_DLL_EXTENSION_INFO);
  126. DWORD outBufferSize = MAX_OUT_BUFFER_SIZE;
  127. DWORD bytesReturned;
  128. DISK_DLL_EXTENSION_INFO inBuffer;
  129. // printf("hOriginal 0x%x hResource 0x%x lpParams 0x%x \n", hOriginal, hResource, lpParams);
  130. //
  131. // Demonstrate how to get various resource info.
  132. //
  133. dwStatus = GetResourceInfo( hOriginal,
  134. hResource,
  135. lpParams );
  136. //////////////////////////////////////////////////////////////////////////
  137. //
  138. // Demonstrate calling into the disk extension DLL.
  139. //
  140. //////////////////////////////////////////////////////////////////////////
  141. printf("\nStarting disk extension DLL tests \n");
  142. outBuffer = LocalAlloc( LPTR, outBufferSize );
  143. if ( !outBuffer ) {
  144. dwStatus = GetLastError();
  145. goto FnExit;
  146. }
  147. //////////////////////////////////////////////////////////////////////////
  148. //
  149. // Buffer verification tests
  150. //
  151. //////////////////////////////////////////////////////////////////////////
  152. //
  153. // No input buffer - should fail.
  154. //
  155. dwStatus = ClusterResourceControl( hResource,
  156. NULL,
  157. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  158. NULL, // Error
  159. inBufferSize,
  160. outBuffer,
  161. outBufferSize,
  162. &bytesReturned );
  163. printf("Input buffer missing: %d [failure expected] \n", dwStatus);
  164. PrintError(dwStatus);
  165. //
  166. // Incorrect input buffer size - should fail.
  167. //
  168. dwStatus = ClusterResourceControl( hResource,
  169. NULL,
  170. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  171. &inBuffer,
  172. 28, // Error
  173. outBuffer,
  174. outBufferSize,
  175. &bytesReturned );
  176. printf("Input buffer size incorrect: %d [failure expected] \n", dwStatus);
  177. PrintError(dwStatus);
  178. //
  179. // Input buffer incorrect version - should fail.
  180. //
  181. ZeroMemory( &inBuffer, sizeof(inBuffer) );
  182. inBuffer.MajorVersion = NT4_MAJOR_VERSION; // Error
  183. dwStatus = ClusterResourceControl( hResource,
  184. NULL,
  185. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  186. &inBuffer,
  187. inBufferSize,
  188. outBuffer,
  189. outBufferSize,
  190. &bytesReturned );
  191. printf("Input buffer version incorrect: %d [failure expected] \n", dwStatus);
  192. PrintError(dwStatus);
  193. //
  194. // No output buffer - should fail.
  195. //
  196. ZeroMemory( &inBuffer, sizeof(inBuffer) );
  197. dwStatus = ClusterResourceControl( hResource,
  198. NULL,
  199. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  200. &inBuffer,
  201. inBufferSize,
  202. NULL, // Error
  203. outBufferSize,
  204. &bytesReturned );
  205. printf("Output buffer missing: %d [failure expected] \n", dwStatus);
  206. PrintError(dwStatus);
  207. //////////////////////////////////////////////////////////////////////////
  208. //
  209. // DLL verification tests
  210. //
  211. //////////////////////////////////////////////////////////////////////////
  212. //
  213. // Disk resource has hard-coded DLL name. A call with any invalid
  214. // proc name will always fail.
  215. //
  216. ZeroMemory( &inBuffer, sizeof(inBuffer) );
  217. inBuffer.MajorVersion = NT5_MAJOR_VERSION;
  218. strncpy( inBuffer.DllModuleName,
  219. MODULE_NAME_INVALID,
  220. RTL_NUMBER_OF( inBuffer.DllModuleName ) - 1 );
  221. strncpy( inBuffer.DllProcName,
  222. PROC_NAME_INVALID,
  223. RTL_NUMBER_OF( inBuffer.DllProcName ) - 1 );
  224. dwStatus = ClusterResourceControl( hResource,
  225. NULL,
  226. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  227. &inBuffer,
  228. inBufferSize,
  229. outBuffer,
  230. outBufferSize,
  231. &bytesReturned );
  232. printf("DLL name invalid: %d [failure expected] \n", dwStatus);
  233. PrintError(dwStatus);
  234. //
  235. // Valid ASR DLL, invalid proc name - should fail.
  236. //
  237. ZeroMemory( &inBuffer, sizeof(inBuffer) );
  238. inBuffer.MajorVersion = NT5_MAJOR_VERSION;
  239. strncpy( inBuffer.DllModuleName,
  240. SYSSETUP_DLL,
  241. RTL_NUMBER_OF( inBuffer.DllModuleName ) - 1 );
  242. strncpy( inBuffer.DllProcName,
  243. PROC_NAME_INVALID,
  244. RTL_NUMBER_OF( inBuffer.DllProcName ) - 1 );
  245. dwStatus = ClusterResourceControl( hResource,
  246. NULL,
  247. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  248. &inBuffer,
  249. inBufferSize,
  250. outBuffer,
  251. outBufferSize,
  252. &bytesReturned );
  253. printf("DLL valid, Proc invalid: %d [failure expected] \n", dwStatus);
  254. PrintError(dwStatus);
  255. #if ALLOW_DLL_PARMS
  256. //
  257. // DLL procedure generates exception - should fail gracefully.
  258. //
  259. ZeroMemory( &inBuffer, sizeof(inBuffer) );
  260. inBuffer.MajorVersion = NT5_MAJOR_VERSION;
  261. strncpy( inBuffer.DllModuleName,
  262. MODULE_NAME_VALID,
  263. RTL_NUMBER_OF( inBuffer.DllModuleName ) - 1 );
  264. strncpy( inBuffer.DllProcName,
  265. PROC_EXCEPTION,
  266. RTL_NUMBER_OF( inBuffer.DllProcName ) - 1 );
  267. dwStatus = ClusterResourceControl( hResource,
  268. NULL,
  269. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  270. &inBuffer,
  271. inBufferSize,
  272. outBuffer,
  273. outBufferSize,
  274. &bytesReturned );
  275. printf("DLL proc generates exception: %d (0x%x) [failure expected] \n", dwStatus, dwStatus);
  276. PrintError(dwStatus);
  277. #if 0
  278. //
  279. // We can't protect against this type of error, so don't test it.
  280. //
  281. //
  282. // DLL procedure has less parameters then we are calling - should fail gracefully.
  283. //
  284. ZeroMemory( &inBuffer, sizeof(inBuffer) );
  285. inBuffer.MajorVersion = NT5_MAJOR_VERSION;
  286. strncpy( inBuffer.DllModuleName,
  287. MODULE_NAME_VALID,
  288. RTL_NUMBER_OF( inBuffer.DllModuleName ) - 1 );
  289. strncpy( inBuffer.DllProcName,
  290. PROC_NOT_ENOUGH_PARMS,
  291. RTL_NUMBER_OF( inBuffer.DllProcName ) - 1 );
  292. dwStatus = ClusterResourceControl( hResource,
  293. NULL,
  294. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  295. &inBuffer,
  296. inBufferSize,
  297. outBuffer,
  298. outBufferSize,
  299. &bytesReturned );
  300. printf("DLL proc doesn't support required number of parms: %d [failure expected] \n", dwStatus);
  301. PrintError(dwStatus);
  302. //
  303. // DLL procedure has more parameters then we are calling - should fail gracefully.
  304. //
  305. ZeroMemory( &inBuffer, sizeof(inBuffer) );
  306. inBuffer.MajorVersion = NT5_MAJOR_VERSION;
  307. strncpy( inBuffer.DllModuleName,
  308. MODULE_NAME_VALID,
  309. RTL_NUMBER_OF( inBuffer.DllModuleName ) - 1 );
  310. strncpy( inBuffer.DllProcName,
  311. PROC_TOO_MANY_PARMS,
  312. RTL_NUMBER_OF( inBuffer.DllProcName ) - 1 );
  313. dwStatus = ClusterResourceControl( hResource,
  314. NULL,
  315. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  316. &inBuffer,
  317. inBufferSize,
  318. outBuffer,
  319. outBufferSize,
  320. &bytesReturned );
  321. printf("DLL proc supports more parms than expected: %d [failure expected] \n", dwStatus);
  322. PrintError(dwStatus);
  323. #endif
  324. //
  325. // DLL procedure returns error based on context.
  326. //
  327. ZeroMemory( &inBuffer, sizeof(inBuffer) );
  328. inBuffer.MajorVersion = NT5_MAJOR_VERSION;
  329. strncpy( inBuffer.DllModuleName,
  330. MODULE_NAME_VALID,
  331. RTL_NUMBER_OF( inBuffer.DllModuleName ) - 1 );
  332. strncpy( inBuffer.DllProcName,
  333. PROC_CONTEXT_AS_ERROR,
  334. RTL_NUMBER_OF( inBuffer.DllProcName ) - 1 );
  335. strncpy( inBuffer.ContextStr,
  336. CONTEXT_ERROR_STR,
  337. RTL_NUMBER_OF( inBuffer.ContextStr ) - 1 );
  338. dwStatus = ClusterResourceControl( hResource,
  339. NULL,
  340. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  341. &inBuffer,
  342. inBufferSize,
  343. outBuffer,
  344. outBufferSize,
  345. &bytesReturned );
  346. printf("DLL proc returns error based on context (%s) : %d [failure expected] \n",
  347. CONTEXT_ERROR_STR,
  348. dwStatus);
  349. PrintError(dwStatus);
  350. #endif // ALLOW_DLL_PARMS
  351. ////////////////////////////////////
  352. // Check: AsrpGetLocalDiskInfo
  353. ////////////////////////////////////
  354. //
  355. // Amount of data returned is larger than the buffer we specified. Should
  356. // indicate an error and bytesReturned should show how many bytes we need.
  357. //
  358. ZeroMemory( &inBuffer, sizeof(inBuffer) );
  359. inBuffer.MajorVersion = NT5_MAJOR_VERSION;
  360. strncpy( inBuffer.DllModuleName,
  361. SYSSETUP_DLL,
  362. RTL_NUMBER_OF( inBuffer.DllModuleName ) - 1 );
  363. strncpy( inBuffer.DllProcName,
  364. ASRP_GET_LOCAL_DISK_INFO,
  365. RTL_NUMBER_OF( inBuffer.DllProcName ) - 1 );
  366. dwStatus = ClusterResourceControl( hResource,
  367. NULL,
  368. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  369. &inBuffer,
  370. inBufferSize,
  371. outBuffer,
  372. 1,
  373. &bytesReturned );
  374. printf("Output buffer too small (bytes returned %d): %d [failure expected] \n", bytesReturned, dwStatus);
  375. PrintError(dwStatus);
  376. if ( 0 == bytesReturned ) {
  377. printf("Bytes returned is zero, stopping. \n");
  378. goto FnExit;
  379. }
  380. if ( ERROR_MORE_DATA != dwStatus ) {
  381. printf("Unexpected status returned, stopping. \n");
  382. goto FnExit;
  383. }
  384. //
  385. // This valid ASR routine should work.
  386. //
  387. ZeroMemory( &inBuffer, sizeof(inBuffer) );
  388. inBuffer.MajorVersion = NT5_MAJOR_VERSION;
  389. strncpy( inBuffer.DllModuleName,
  390. SYSSETUP_DLL,
  391. RTL_NUMBER_OF( inBuffer.DllModuleName ) - 1 );
  392. strncpy( inBuffer.DllProcName,
  393. ASRP_GET_LOCAL_DISK_INFO,
  394. RTL_NUMBER_OF( inBuffer.DllProcName ) - 1 );
  395. LocalFree( outBuffer );
  396. outBuffer = NULL;
  397. outBufferSize = bytesReturned + 1;
  398. outBuffer = LocalAlloc( LPTR, outBufferSize );
  399. if ( !outBuffer ) {
  400. dwStatus = GetLastError();
  401. printf("Unable to allocate real buffer size %d bytes, error %d \n",
  402. outBufferSize,
  403. dwStatus);
  404. PrintError(dwStatus);
  405. goto FnExit;
  406. }
  407. dwStatus = ClusterResourceControl( hResource,
  408. NULL,
  409. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  410. &inBuffer,
  411. inBufferSize,
  412. outBuffer,
  413. outBufferSize,
  414. &bytesReturned );
  415. printf("Returned buffer size %d (0x%x) and status %d [success expected] \n",
  416. bytesReturned,
  417. bytesReturned,
  418. dwStatus);
  419. printf("\nDLL: %s Proc: %s \n\n",
  420. inBuffer.DllModuleName,
  421. inBuffer.DllProcName );
  422. PrintError(dwStatus);
  423. if ( NO_ERROR == dwStatus ) {
  424. DumpBuffer( outBuffer, bytesReturned );
  425. }
  426. ////////////////////////////////////
  427. // Check: AsrpGetLocalVolumeInfo
  428. ////////////////////////////////////
  429. //
  430. // Amount of data returned is larger than the buffer we specified. Should
  431. // indicate an error and bytesReturned should show how many bytes we need.
  432. //
  433. ZeroMemory( &inBuffer, sizeof(inBuffer) );
  434. inBuffer.MajorVersion = NT5_MAJOR_VERSION;
  435. strncpy( inBuffer.DllModuleName,
  436. SYSSETUP_DLL,
  437. RTL_NUMBER_OF( inBuffer.DllModuleName ) - 1 );
  438. strncpy( inBuffer.DllProcName,
  439. ASRP_GET_LOCAL_VOLUME_INFO,
  440. RTL_NUMBER_OF( inBuffer.DllProcName ) - 1 );
  441. dwStatus = ClusterResourceControl( hResource,
  442. NULL,
  443. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  444. &inBuffer,
  445. inBufferSize,
  446. outBuffer,
  447. 1,
  448. &bytesReturned );
  449. printf("Output buffer too small (bytes returned %d): %d [failure expected] \n", bytesReturned, dwStatus);
  450. PrintError(dwStatus);
  451. if ( 0 == bytesReturned ) {
  452. printf("Bytes returned is zero, stopping. \n");
  453. goto FnExit;
  454. }
  455. if ( ERROR_MORE_DATA != dwStatus ) {
  456. printf("Unexpected status returned, stopping. \n");
  457. goto FnExit;
  458. }
  459. //
  460. // This valid ASR routine should work.
  461. //
  462. ZeroMemory( &inBuffer, sizeof(inBuffer) );
  463. inBuffer.MajorVersion = NT5_MAJOR_VERSION;
  464. strncpy( inBuffer.DllModuleName,
  465. SYSSETUP_DLL,
  466. RTL_NUMBER_OF( inBuffer.DllModuleName ) - 1 );
  467. strncpy( inBuffer.DllProcName,
  468. ASRP_GET_LOCAL_VOLUME_INFO,
  469. RTL_NUMBER_OF( inBuffer.DllProcName ) - 1 );
  470. LocalFree( outBuffer );
  471. outBuffer = NULL;
  472. outBufferSize = bytesReturned + 1;
  473. outBuffer = LocalAlloc( LPTR, outBufferSize );
  474. if ( !outBuffer ) {
  475. dwStatus = GetLastError();
  476. printf("Unable to allocate real buffer size %d bytes, error %d \n",
  477. outBufferSize,
  478. dwStatus);
  479. PrintError(dwStatus);
  480. goto FnExit;
  481. }
  482. dwStatus = ClusterResourceControl( hResource,
  483. NULL,
  484. CLUSCTL_RESOURCE_STORAGE_DLL_EXTENSION,
  485. &inBuffer,
  486. inBufferSize,
  487. outBuffer,
  488. outBufferSize,
  489. &bytesReturned );
  490. printf("Returned buffer size %d (0x%x) and status %d [success expected] \n",
  491. bytesReturned,
  492. bytesReturned,
  493. dwStatus);
  494. printf("\nDLL: %s Proc: %s \n\n",
  495. inBuffer.DllModuleName,
  496. inBuffer.DllProcName );
  497. PrintError(dwStatus);
  498. if ( NO_ERROR == dwStatus ) {
  499. DumpBuffer( outBuffer, bytesReturned );
  500. }
  501. FnExit:
  502. if ( outBuffer ) {
  503. LocalFree( outBuffer);
  504. }
  505. //
  506. // If you return any kind of error, the enumeration stops. Since we want to enumerate all
  507. // the disks, always return success.
  508. //
  509. return NO_ERROR;
  510. } // ResourceCallBack
  511. DWORD
  512. GetResourceInfo(
  513. RESOURCE_HANDLE hOriginal,
  514. RESOURCE_HANDLE hResource,
  515. PVOID lpParams
  516. )
  517. {
  518. DWORD dwSignature;
  519. DWORD dwStatus;
  520. RESOURCE_STATE resState;
  521. ZeroMemory( &resState, sizeof(RESOURCE_STATE) );
  522. dwStatus = GetSignature( hResource, &dwSignature );
  523. if ( NO_ERROR != dwStatus ) {
  524. printf("Unable to get signature: %d \n", dwStatus);
  525. PrintError(dwStatus);
  526. goto FnExit;
  527. }
  528. dwStatus = GetResourceState( hResource, &resState );
  529. if ( NO_ERROR != dwStatus ) {
  530. printf("Unable to get resource state: %d \n", dwStatus);
  531. PrintError(dwStatus);
  532. goto FnExit;
  533. }
  534. printf("\n");
  535. printf("Signature: %08X \n", dwSignature);
  536. printf("Node : %ws \n", resState.ResNodeName);
  537. printf("Group : %ws \n", resState.ResGroupName);
  538. printf("Status : %08X - ", resState.State);
  539. switch( resState.State )
  540. {
  541. case ClusterResourceInherited:
  542. printf("Inherited");
  543. break;
  544. case ClusterResourceInitializing:
  545. printf("Initializing");
  546. break;
  547. case ClusterResourceOnline:
  548. printf("Online");
  549. break;
  550. case ClusterResourceOffline:
  551. printf("Offline");
  552. break;
  553. case ClusterResourceFailed:
  554. printf("Failed");
  555. break;
  556. case ClusterResourcePending:
  557. printf("Pending");
  558. break;
  559. case ClusterResourceOnlinePending:
  560. printf("Online Pending");
  561. break;
  562. case ClusterResourceOfflinePending:
  563. printf("Offline Pending");
  564. break;
  565. default:
  566. printf("Unknown");
  567. }
  568. printf("\n");
  569. FnExit:
  570. if ( resState.ResNodeName ) {
  571. LocalFree( resState.ResNodeName );
  572. }
  573. if ( resState.ResGroupName ) {
  574. LocalFree( resState.ResGroupName );
  575. }
  576. return dwStatus;
  577. } // GetResourceInfo
  578. DWORD
  579. GetResourceState(
  580. HRESOURCE Resource,
  581. PRESOURCE_STATE ResState
  582. )
  583. {
  584. CLUSTER_RESOURCE_STATE nState;
  585. LPWSTR lpszResNodeName = NULL;
  586. LPWSTR lpszResGroupName = NULL;
  587. DWORD dwStatus = NO_ERROR;
  588. nState = WrapGetClusterResourceState( Resource,
  589. &lpszResNodeName,
  590. &lpszResGroupName
  591. );
  592. if ( nState == ClusterResourceStateUnknown ) {
  593. dwStatus = GetLastError();
  594. printf("WrapGetClusterResourceState failed: %d \n", dwStatus);
  595. PrintError(dwStatus);
  596. goto FnExit;
  597. }
  598. ResState->State = nState;
  599. ResState->ResNodeName = lpszResNodeName;
  600. ResState->ResGroupName = lpszResGroupName;
  601. FnExit:
  602. return dwStatus;
  603. } // GetResourceState
  604. DWORD
  605. DisplayResourceName(
  606. RESOURCE_HANDLE hResource
  607. )
  608. {
  609. LPWSTR lpszOutBuffer = NULL;
  610. DWORD dwStatus;
  611. DWORD dwBytesReturned;
  612. dwStatus = WrapClusterResourceControl( hResource,
  613. CLUSCTL_RESOURCE_GET_NAME,
  614. &lpszOutBuffer,
  615. &dwBytesReturned );
  616. if ( NO_ERROR == dwStatus ) {
  617. wprintf( L"Resource Name: %ls\n", lpszOutBuffer );
  618. } else {
  619. printf("CLUSCTL_RESOURCE_GET_NAME failed: %d \n", dwStatus);
  620. PrintError(dwStatus);
  621. }
  622. if (lpszOutBuffer) {
  623. LocalFree(lpszOutBuffer);
  624. }
  625. return dwStatus;
  626. } // DisplayResourceName
  627. DWORD
  628. GetSignature(
  629. RESOURCE_HANDLE hResource,
  630. DWORD *dwSignature
  631. )
  632. {
  633. PBYTE outBuffer = NULL;
  634. DWORD dwStatus;
  635. DWORD dwBytesReturned;
  636. dwStatus = WrapClusterResourceControl( hResource,
  637. CLUSCTL_RESOURCE_STORAGE_GET_DISK_INFO,
  638. &outBuffer,
  639. &dwBytesReturned );
  640. if ( NO_ERROR == dwStatus ) {
  641. if ( !GetSignatureFromDiskInfo(outBuffer, dwSignature, dwBytesReturned) ) {
  642. printf("Unable to get signature from DiskInfo. \n");
  643. dwStatus = ERROR_BAD_FORMAT;
  644. }
  645. } else {
  646. printf("CLUSCTL_RESOURCE_STORAGE_GET_DISK_INFO failed: %d \n", dwStatus);
  647. PrintError(dwStatus);
  648. }
  649. if (outBuffer) {
  650. LocalFree(outBuffer);
  651. }
  652. return dwStatus;
  653. } // GetSignature
  654. BOOLEAN
  655. GetSignatureFromDiskInfo(
  656. PBYTE DiskInfo,
  657. DWORD *Signature,
  658. DWORD DiskInfoSize
  659. )
  660. {
  661. #if TEST_PARSE_ROUTINE
  662. PCLUSPROP_DISK_NUMBER diskNumber = NULL;
  663. PCLUSPROP_SCSI_ADDRESS scsiAddress = NULL;
  664. PCLUSPROP_PARTITION_INFO partInfo = NULL;
  665. PBYTE junkInfo = NULL;
  666. PDWORD dumpInfo = (PDWORD)DiskInfo;
  667. #endif
  668. PCLUSPROP_DISK_SIGNATURE diskSignature = NULL;
  669. diskSignature = (PCLUSPROP_DISK_SIGNATURE)ParseDiskInfo( DiskInfo,
  670. DiskInfoSize,
  671. CLUSPROP_SYNTAX_DISK_SIGNATURE );
  672. if ( !diskSignature ) {
  673. return FALSE;
  674. }
  675. *Signature = diskSignature->dw;
  676. #if TEST_PARSE_ROUTINE
  677. diskNumber = (PCLUSPROP_DISK_NUMBER)ParseDiskInfo( DiskInfo,
  678. DiskInfoSize,
  679. CLUSPROP_SYNTAX_DISK_NUMBER );
  680. if ( diskNumber ) {
  681. printf("diskNumber->Syntax: %08X \n", diskNumber->Syntax);
  682. printf("diskNumber->cbLength: %08X \n", diskNumber->cbLength);
  683. printf("diskNumber->dw: %08X \n", diskNumber->dw);
  684. }
  685. scsiAddress = (PCLUSPROP_SCSI_ADDRESS)ParseDiskInfo( DiskInfo,
  686. DiskInfoSize,
  687. CLUSPROP_SYNTAX_SCSI_ADDRESS );
  688. if ( scsiAddress ) {
  689. printf("scsiAddress->Syntax: %08X \n", scsiAddress->Syntax);
  690. printf("scsiAddress->cbLength: %08X \n", scsiAddress->cbLength);
  691. printf("scsiAddress->PortNumber: %02X \n", scsiAddress->PortNumber);
  692. printf("scsiAddress->PathId: %02X \n", scsiAddress->PathId);
  693. printf("scsiAddress->TargetId: %02X \n", scsiAddress->TargetId);
  694. printf("scsiAddress->Lun: %02X \n", scsiAddress->Lun);
  695. }
  696. partInfo = (PCLUSPROP_PARTITION_INFO)ParseDiskInfo( DiskInfo,
  697. DiskInfoSize,
  698. CLUSPROP_SYNTAX_PARTITION_INFO );
  699. if ( partInfo ) {
  700. printf("Partition info... \n");
  701. }
  702. //
  703. // The following should fail...
  704. //
  705. junkInfo = ParseDiskInfo( DiskInfo,
  706. DiskInfoSize,
  707. -1 );
  708. if (junkInfo) {
  709. printf("Problem parsing list. Used invalid syntax and pointer returned! \n");
  710. }
  711. #endif
  712. return TRUE;
  713. } // GetSignatureFromDiskInfo
  714. LPBYTE
  715. ParseDiskInfo(
  716. PBYTE DiskInfo,
  717. DWORD DiskInfoSize,
  718. DWORD SyntaxValue
  719. )
  720. {
  721. CLUSPROP_BUFFER_HELPER ListEntry; // used to parse the value list
  722. DWORD cbOffset = 0; // offset to next entry in the value list
  723. DWORD cbPosition = 0; // tracks the advance through the value list buffer
  724. LPBYTE returnPtr = 0;
  725. ListEntry.pb = DiskInfo;
  726. while (TRUE) {
  727. if ( CLUSPROP_SYNTAX_ENDMARK == *ListEntry.pdw ) {
  728. break;
  729. }
  730. cbOffset = ALIGN_CLUSPROP( ListEntry.pValue->cbLength + sizeof(CLUSPROP_VALUE) );
  731. //
  732. // Check for specific syntax in the property list.
  733. //
  734. if ( SyntaxValue == *ListEntry.pdw ) {
  735. //
  736. // Make sure the complete entry fits in the buffer specified.
  737. //
  738. if ( cbPosition + cbOffset > DiskInfoSize ) {
  739. printf("Possibly corrupt list! \n");
  740. } else {
  741. returnPtr = ListEntry.pb;
  742. }
  743. break;
  744. }
  745. //
  746. // Verify that the offset to the next entry is
  747. // within the value list buffer, then advance
  748. // the CLUSPROP_BUFFER_HELPER pointer.
  749. //
  750. cbPosition += cbOffset;
  751. if ( cbPosition > DiskInfoSize ) break;
  752. ListEntry.pb += cbOffset;
  753. }
  754. return returnPtr;
  755. } // ParseDiskInfo
  756. VOID
  757. PrintError(
  758. IN DWORD ErrorCode
  759. )
  760. {
  761. LPVOID lpMsgBuf;
  762. ULONG count;
  763. count = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  764. FORMAT_MESSAGE_FROM_SYSTEM |
  765. FORMAT_MESSAGE_IGNORE_INSERTS,
  766. NULL,
  767. ErrorCode,
  768. 0,
  769. (LPTSTR) &lpMsgBuf,
  770. 0,
  771. NULL
  772. );
  773. if (count != 0) {
  774. printf(" (%d) %s\n", ErrorCode, (LPCTSTR) lpMsgBuf);
  775. LocalFree( lpMsgBuf );
  776. } else {
  777. printf("Format message failed. Error: %d\n", GetLastError());
  778. }
  779. } // PrintError
  780. DWORD
  781. WrapClusterResourceControl(
  782. RESOURCE_HANDLE hResource,
  783. DWORD dwControlCode,
  784. LPVOID *OutBuffer,
  785. DWORD *dwBytesReturned
  786. )
  787. {
  788. DWORD dwStatus;
  789. DWORD cbOutBufferSize = MAX_NAME_SIZE;
  790. DWORD cbResultSize = MAX_NAME_SIZE;
  791. LPVOID tempOutBuffer = LocalAlloc( LPTR, cbOutBufferSize );
  792. dwStatus = ClusterResourceControl( hResource,
  793. NULL,
  794. dwControlCode,
  795. NULL,
  796. 0,
  797. tempOutBuffer,
  798. cbOutBufferSize,
  799. &cbResultSize );
  800. //
  801. // Reallocation routine if buffer is too small
  802. //
  803. if ( ERROR_MORE_DATA == dwStatus )
  804. {
  805. LocalFree( tempOutBuffer );
  806. cbOutBufferSize = cbResultSize;
  807. tempOutBuffer = LocalAlloc( LPTR, cbOutBufferSize );
  808. dwStatus = ClusterResourceControl( hResource,
  809. NULL,
  810. dwControlCode,
  811. NULL,
  812. 0,
  813. tempOutBuffer,
  814. cbOutBufferSize,
  815. &cbResultSize );
  816. }
  817. //
  818. // On success, give the user the allocated buffer. The user is responsible
  819. // for freeing this buffer. On failure, free the buffer and return a status.
  820. //
  821. if ( NO_ERROR == dwStatus ) {
  822. *OutBuffer = tempOutBuffer;
  823. *dwBytesReturned = cbResultSize;
  824. } else {
  825. *OutBuffer = NULL;
  826. *dwBytesReturned = 0;
  827. LocalFree( tempOutBuffer );
  828. }
  829. return dwStatus;
  830. } // WrapClusterResourceControl
  831. CLUSTER_RESOURCE_STATE WINAPI WrapGetClusterResourceState(
  832. IN HRESOURCE hResource,
  833. OUT OPTIONAL LPWSTR * ppwszNodeName,
  834. OUT OPTIONAL LPWSTR * ppwszGroupName
  835. )
  836. {
  837. CLUSTER_RESOURCE_STATE cState = ClusterResourceStateUnknown;
  838. LPWSTR pwszNodeName = NULL;
  839. DWORD cchNodeName = 128;
  840. LPWSTR pwszGroupName = NULL;
  841. DWORD cchGroupName = 128;
  842. DWORD cchTempNodeName = cchNodeName;
  843. DWORD cchTempGroupName = cchGroupName;
  844. // Zero the out parameters
  845. if ( ppwszNodeName != NULL )
  846. {
  847. *ppwszNodeName = NULL;
  848. }
  849. if ( ppwszGroupName != NULL )
  850. {
  851. *ppwszGroupName = NULL;
  852. }
  853. pwszNodeName = (LPWSTR) LocalAlloc( LPTR, cchNodeName * sizeof( *pwszNodeName ) );
  854. if ( pwszNodeName != NULL )
  855. {
  856. pwszGroupName = (LPWSTR) LocalAlloc( LPTR, cchGroupName * sizeof( *pwszGroupName ) );
  857. if ( pwszGroupName != NULL )
  858. {
  859. cState = GetClusterResourceState( hResource, pwszNodeName, &cchTempNodeName, pwszGroupName, &cchTempGroupName );
  860. if ( GetLastError() == ERROR_MORE_DATA )
  861. {
  862. cState = ClusterResourceStateUnknown; // reset to error condition
  863. LocalFree( pwszNodeName );
  864. pwszNodeName = NULL;
  865. cchNodeName = ++cchTempNodeName;
  866. LocalFree( pwszGroupName );
  867. pwszGroupName = NULL;
  868. cchGroupName = ++cchTempGroupName;
  869. pwszNodeName = (LPWSTR) LocalAlloc( LPTR, cchNodeName * sizeof( *pwszNodeName ) );
  870. if ( pwszNodeName != NULL )
  871. {
  872. pwszGroupName = (LPWSTR) LocalAlloc( LPTR, cchGroupName * sizeof( *pwszGroupName ) );
  873. if ( pwszGroupName != NULL )
  874. {
  875. cState = GetClusterResourceState( hResource,
  876. pwszNodeName,
  877. &cchNodeName,
  878. pwszGroupName,
  879. &cchGroupName );
  880. }
  881. }
  882. }
  883. }
  884. }
  885. //
  886. // if there was not an error and the argument was not NULL, then return the string.
  887. //
  888. if ( ( cState != ClusterResourceStateUnknown ) && ( ppwszNodeName != NULL ) )
  889. {
  890. *ppwszNodeName = pwszNodeName;
  891. }
  892. //
  893. // if there was not an error and the argument was not NULL, then return the string.
  894. //
  895. if ( ( cState != ClusterResourceStateUnknown ) && ( ppwszGroupName != NULL ) )
  896. {
  897. *ppwszGroupName = pwszGroupName;
  898. }
  899. //
  900. // if there was an error or the argument was NULL, then free the string.
  901. //
  902. if ( ( cState == ClusterResourceStateUnknown ) || ( ppwszNodeName == NULL ) )
  903. {
  904. LocalFree( pwszNodeName );
  905. }
  906. //
  907. // if there was an error or the argument was NULL, then free the string.
  908. //
  909. if ( ( cState == ClusterResourceStateUnknown ) || ( ppwszGroupName == NULL ) )
  910. {
  911. LocalFree( pwszGroupName );
  912. }
  913. return cState;
  914. } //*** WrapGetClusterResourceState()
  915. #define MAX_COLUMNS 16
  916. VOID
  917. DumpBuffer(
  918. IN PUCHAR Buffer,
  919. IN DWORD ByteCount
  920. )
  921. {
  922. DWORD idx;
  923. DWORD jdx;
  924. DWORD columns;
  925. UCHAR tempC;
  926. if ( !Buffer || !ByteCount ) {
  927. printf("Invalid parameter specified: buffer %p byte count %d \n", Buffer, ByteCount);
  928. return;
  929. }
  930. //
  931. // Print header.
  932. //
  933. printf("\n");
  934. printf(" Address 00 01 02 03 04 05 06 07 - 08 09 0a 0b 0c 0d 0e 0f \n");
  935. printf("--------- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ");
  936. for ( idx = 0; idx < ByteCount; idx += MAX_COLUMNS ) {
  937. if ( idx % MAX_COLUMNS == 0 ) {
  938. printf("\n%08x: ", idx);
  939. }
  940. if ( ByteCount - idx >= MAX_COLUMNS ) {
  941. columns = MAX_COLUMNS;
  942. } else {
  943. columns = ByteCount - idx;
  944. }
  945. for ( jdx = 0; jdx < MAX_COLUMNS; jdx++) {
  946. if ( jdx == 8 ) {
  947. printf("- ");
  948. }
  949. if ( jdx < columns ) {
  950. printf("%02x ", Buffer[idx+jdx]);
  951. } else {
  952. printf(" ");
  953. }
  954. }
  955. printf(" ");
  956. for ( jdx = 0; jdx < columns; jdx++ ) {
  957. tempC = Buffer[idx+jdx];
  958. if ( isprint(tempC) ) {
  959. printf("%c", tempC);
  960. } else {
  961. printf(".");
  962. }
  963. }
  964. }
  965. printf("\n\n");
  966. } // DumpBuffer