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.

795 lines
14 KiB

  1. //***************************************************************************
  2. //
  3. // MAINDLL.CPP
  4. //
  5. // Module: WINMGMT class provider sample code
  6. //
  7. // Purpose: Contains DLL entry points. Also has code that controls
  8. // when the DLL can be unloaded by tracking the number of
  9. // objects and locks as well as routines that support
  10. // self registration.
  11. //
  12. // Copyright (c) 2000 Microsoft Corporation
  13. //
  14. //***************************************************************************
  15. #include <initguid.h>
  16. #include "hbaapip.h"
  17. //
  18. // This is an increasing counter that is used to assign Hba handles in
  19. // response to HbaOpenAdapter calls.
  20. //
  21. ULONG HbaHandleCounter = 1;
  22. //
  23. // This maintains a list of all of the open Hba Handles.
  24. //
  25. LIST_ENTRY HbaHandleList = { &HbaHandleList, &HbaHandleList };
  26. //
  27. // This is the mutex object we use for our critical section
  28. //
  29. HANDLE Mutex;
  30. PADAPTER_HANDLE GetDataByHandle(
  31. HBA_HANDLE HbaHandle
  32. )
  33. {
  34. PADAPTER_HANDLE HandleData;
  35. PADAPTER_HANDLE TargetHandleData = NULL;
  36. PLIST_ENTRY HandleList;
  37. EnterCritSection();
  38. HandleList = HbaHandleList.Flink;
  39. while (HandleList != &HbaHandleList)
  40. {
  41. HandleData = CONTAINING_RECORD(HandleList,
  42. ADAPTER_HANDLE,
  43. List);
  44. if (HandleData->HbaHandle == HbaHandle)
  45. {
  46. TargetHandleData = HandleData;
  47. break;
  48. }
  49. }
  50. LeaveCritSection();
  51. return(TargetHandleData);
  52. }
  53. #define ALL_DATA_SIZE_GUESS 0x1000
  54. ULONG QueryAllData(
  55. HANDLE Handle,
  56. PWNODE_ALL_DATA *Wnode
  57. )
  58. {
  59. ULONG SizeNeeded;
  60. PUCHAR Buffer;
  61. ULONG Status;
  62. SizeNeeded = ALL_DATA_SIZE_GUESS;
  63. Buffer = AllocMemory(SizeNeeded);
  64. if (Buffer != NULL)
  65. {
  66. Status = WmiQueryAllDataW(Handle,
  67. &SizeNeeded,
  68. Buffer);
  69. if (Status == ERROR_INSUFFICIENT_BUFFER)
  70. {
  71. FreeMemory(Buffer);
  72. Buffer = AllocMemory(SizeNeeded);
  73. if (Buffer != NULL)
  74. {
  75. Status = WmiQueryAllDataW(Handle,
  76. &SizeNeeded,
  77. Buffer);
  78. } else {
  79. Status = ERROR_NOT_ENOUGH_MEMORY;
  80. }
  81. }
  82. } else {
  83. Status = ERROR_NOT_ENOUGH_MEMORY;
  84. }
  85. if ((Status != ERROR_SUCCESS) &&
  86. (Status != ERROR_NOT_ENOUGH_MEMORY))
  87. {
  88. FreeMemory(Buffer);
  89. }
  90. *Wnode = (PWNODE_ALL_DATA)Buffer;
  91. return(Status);
  92. }
  93. #define EXEC_METHOD_GUESS 0x400
  94. ULONG ExecuteMethod(
  95. HANDLE Handle,
  96. PWCHAR InstanceName,
  97. ULONG MethodId,
  98. ULONG InBufferSize,
  99. PUCHAR InBuffer,
  100. ULONG *OutBufferSize,
  101. PUCHAR *OutBuffer
  102. )
  103. {
  104. ULONG SizeNeeded;
  105. PUCHAR Buffer;
  106. ULONG Status;
  107. SizeNeeded = EXEC_METHOD_GUESS;
  108. Buffer = AllocMemory(SizeNeeded);
  109. if (Buffer != NULL)
  110. {
  111. Status = WmiExecuteMethodW(Handle,
  112. InstanceName,
  113. MethodId,
  114. InBufferSize,
  115. InBuffer,
  116. &SizeNeeded,
  117. Buffer);
  118. if (Status == ERROR_INSUFFICIENT_BUFFER)
  119. {
  120. FreeMemory(Buffer);
  121. Buffer = AllocMemory(SizeNeeded);
  122. if (Buffer != NULL)
  123. {
  124. Status = WmiExecuteMethodW(Handle,
  125. InstanceName,
  126. MethodId,
  127. InBufferSize,
  128. InBuffer,
  129. &SizeNeeded,
  130. Buffer);
  131. if (Status != ERROR_SUCCESS)
  132. {
  133. FreeMemory(Buffer);
  134. } else {
  135. *OutBufferSize = SizeNeeded;
  136. *OutBuffer = Buffer;
  137. }
  138. } else {
  139. Status = ERROR_NOT_ENOUGH_MEMORY;
  140. }
  141. } else if (Status == ERROR_SUCCESS) {
  142. *OutBufferSize = SizeNeeded;
  143. *OutBuffer = Buffer;
  144. } else {
  145. FreeMemory(Buffer);
  146. }
  147. } else {
  148. Status = ERROR_NOT_ENOUGH_MEMORY;
  149. }
  150. return(Status);
  151. }
  152. #define SINGLE_INSTANCE_SIZE_GUESS 0x400
  153. ULONG QuerySingleInstance(
  154. HANDLE Handle,
  155. PWCHAR InstanceName,
  156. PWNODE_SINGLE_INSTANCE *Wnode
  157. )
  158. {
  159. ULONG SizeNeeded;
  160. PUCHAR Buffer;
  161. ULONG Status;
  162. SizeNeeded = SINGLE_INSTANCE_SIZE_GUESS;
  163. Buffer = AllocMemory(SizeNeeded);
  164. if (Buffer != NULL)
  165. {
  166. Status = WmiQuerySingleInstanceW(Handle,
  167. InstanceName,
  168. &SizeNeeded,
  169. Buffer);
  170. if (Status == ERROR_INSUFFICIENT_BUFFER)
  171. {
  172. FreeMemory(Buffer);
  173. Buffer = AllocMemory(SizeNeeded);
  174. if (Buffer != NULL)
  175. {
  176. Status = WmiQuerySingleInstanceW(Handle,
  177. InstanceName,
  178. &SizeNeeded,
  179. Buffer);
  180. } else {
  181. Status = ERROR_NOT_ENOUGH_MEMORY;
  182. }
  183. }
  184. } else {
  185. Status = ERROR_NOT_ENOUGH_MEMORY;
  186. }
  187. if ((Status != ERROR_SUCCESS) &&
  188. (Status != ERROR_NOT_ENOUGH_MEMORY))
  189. {
  190. FreeMemory(Buffer);
  191. }
  192. *Wnode = (PWNODE_SINGLE_INSTANCE)Buffer;
  193. return(Status);
  194. }
  195. ULONG ParseAllData(
  196. PWNODE_ALL_DATA Wnode,
  197. ULONG *CountPtr,
  198. PUSHORT **InstanceNamesPtr,
  199. PUCHAR **DataBlocksPtr,
  200. PULONG *DataLengthsPtr
  201. )
  202. {
  203. PUCHAR *DataBlocks;
  204. PUSHORT *Names;
  205. PULONG DataLengths;
  206. PWNODE_ALL_DATA WAD;
  207. ULONG Count, i, Linkage, j;
  208. BOOLEAN IsFixedInstance;
  209. ULONG FixedDataSize;
  210. PUCHAR FixedDataPtr;
  211. PULONG InstanceNameOffsets;
  212. POFFSETINSTANCEDATAANDLENGTH DataOffsetAndLength;
  213. //
  214. // TODO: Validate WNODE being returned
  215. //
  216. //
  217. // Count up all of the instances in the wnodes
  218. //
  219. Linkage = 0;
  220. Count = 0;
  221. WAD = Wnode;
  222. do
  223. {
  224. WAD = (PWNODE_ALL_DATA)OffsetToPtr(WAD, Linkage);
  225. Linkage = WAD->WnodeHeader.Linkage;
  226. Count += WAD->InstanceCount;
  227. } while (Linkage != 0);
  228. Names = (PUSHORT *)AllocMemory(Count * sizeof(PUSHORT));
  229. if (Names == NULL)
  230. {
  231. return(ERROR_NOT_ENOUGH_MEMORY);
  232. }
  233. DataBlocks = (PUCHAR *)AllocMemory(Count * sizeof(PUCHAR));
  234. if (DataBlocks == NULL)
  235. {
  236. FreeMemory(Names);
  237. return(ERROR_NOT_ENOUGH_MEMORY);
  238. }
  239. DataLengths = (ULONG *)AllocMemory(Count * sizeof(ULONG));
  240. if (DataLengths == NULL)
  241. {
  242. FreeMemory(Names);
  243. FreeMemory(DataBlocks);
  244. return(ERROR_NOT_ENOUGH_MEMORY);
  245. }
  246. WAD = Wnode;
  247. Linkage = 0;
  248. i = 0;
  249. do
  250. {
  251. WAD = (PWNODE_ALL_DATA)OffsetToPtr(WAD, Linkage);
  252. InstanceNameOffsets = (PULONG)OffsetToPtr(WAD, WAD->OffsetInstanceNameOffsets);
  253. IsFixedInstance = (WAD->WnodeHeader.Flags &
  254. WNODE_FLAG_FIXED_INSTANCE_SIZE) == WNODE_FLAG_FIXED_INSTANCE_SIZE;
  255. if (IsFixedInstance)
  256. {
  257. FixedDataSize = (WAD->FixedInstanceSize + 7) & ~7;
  258. FixedDataPtr = (PUCHAR)OffsetToPtr(WAD, WAD->DataBlockOffset);
  259. } else {
  260. DataOffsetAndLength = WAD->OffsetInstanceDataAndLength;
  261. }
  262. for (j = 0; j < WAD->InstanceCount; j++, i++)
  263. {
  264. HbaapiAssert(i < Count);
  265. Names[i] = (PUSHORT)OffsetToPtr(WAD, InstanceNameOffsets[j]);
  266. if (IsFixedInstance)
  267. {
  268. DataBlocks[i] = OffsetToPtr(WAD, (FixedDataSize * j));
  269. DataLengths[i] = WAD->FixedInstanceSize;
  270. } else {
  271. DataBlocks[i] = OffsetToPtr(WAD, DataOffsetAndLength[j].OffsetInstanceData);
  272. DataLengths[i] = DataOffsetAndLength[j].LengthInstanceData;
  273. }
  274. }
  275. Linkage = WAD->WnodeHeader.Linkage;
  276. } while (Linkage != 0);
  277. *CountPtr = Count;
  278. if (InstanceNamesPtr != NULL)
  279. {
  280. *InstanceNamesPtr = Names;
  281. } else {
  282. FreeMemory(Names);
  283. }
  284. if (DataBlocksPtr != NULL)
  285. {
  286. *DataBlocksPtr = DataBlocks;
  287. } else {
  288. FreeMemory(DataBlocks);
  289. }
  290. if (DataLengthsPtr != NULL)
  291. {
  292. *DataLengthsPtr = DataLengths;
  293. } else {
  294. FreeMemory(DataLengths);
  295. }
  296. return(ERROR_SUCCESS);
  297. }
  298. ULONG ParseSingleInstance(
  299. PWNODE_SINGLE_INSTANCE SingleInstance,
  300. PUSHORT *InstanceNamePtr,
  301. PUCHAR *DataPtr,
  302. ULONG *DataLenPtr
  303. )
  304. {
  305. ULONG DataLen;
  306. PUCHAR Data;
  307. PUSHORT InstanceName;
  308. //
  309. // TODO: Validate WNODE being returned
  310. //
  311. Data = OffsetToPtr(SingleInstance, SingleInstance->DataBlockOffset);
  312. DataLen = SingleInstance->SizeDataBlock;
  313. InstanceName = (PUSHORT)OffsetToPtr(SingleInstance, SingleInstance->OffsetInstanceName);
  314. if (DataPtr != NULL)
  315. {
  316. *DataPtr = Data;
  317. }
  318. if (InstanceNamePtr != NULL)
  319. {
  320. *InstanceNamePtr = InstanceName;
  321. }
  322. if (DataLenPtr != NULL)
  323. {
  324. *DataLenPtr = DataLen;
  325. }
  326. return (ERROR_SUCCESS);
  327. }
  328. PWCHAR CreatePortInstanceNameW(
  329. PWCHAR AdapterInstanceName,
  330. ULONG PortIndex
  331. )
  332. {
  333. PWCHAR PortName;
  334. PWCHAR AdapterPrefix;
  335. PWCHAR Name = NULL;
  336. ULONG Len, AllocLen;
  337. PWCHAR p;
  338. ULONG i;
  339. Len = wcslen(AdapterInstanceName);
  340. AllocLen = (Len + 1) * sizeof(WCHAR);
  341. AdapterPrefix = AllocMemory(AllocLen);
  342. if (AdapterPrefix != NULL)
  343. {
  344. wcscpy(AdapterPrefix, AdapterInstanceName);
  345. p = AdapterPrefix + Len;
  346. while (p > AdapterPrefix)
  347. {
  348. if (*p == L'_')
  349. {
  350. *p = 0;
  351. break;
  352. }
  353. p--;
  354. }
  355. Name = AllocMemory(AllocLen + (10*sizeof(WCHAR)));
  356. if (Name != NULL)
  357. {
  358. wsprintfW(Name,
  359. L"%ws_%d",
  360. AdapterPrefix,
  361. PortIndex);
  362. }
  363. FreeMemory(AdapterPrefix);
  364. }
  365. return(Name);
  366. }
  367. ULONG UnicodeToAnsi(
  368. LPCWSTR pszW,
  369. LPSTR pszA,
  370. ULONG MaxLen
  371. )
  372. /*++
  373. Routine Description:
  374. Convert Unicode string into its ansi equivalent
  375. Arguments:
  376. pszW is unicode string to convert
  377. pszA on entry has a pointer to buffer to write ansi string
  378. Return Value:
  379. Error code
  380. --*/
  381. {
  382. ULONG cCharacters;
  383. ULONG Status;
  384. ULONG cbAnsiUsed;
  385. //
  386. // If input is null then just return empty
  387. if (pszW == NULL)
  388. {
  389. *pszA = 0;
  390. return(ERROR_SUCCESS);
  391. }
  392. cCharacters = wcslen(pszW)+1;
  393. // Convert to ANSI.
  394. cbAnsiUsed = WideCharToMultiByte(CP_ACP,
  395. 0,
  396. pszW,
  397. cCharacters,
  398. pszA,
  399. MaxLen,
  400. NULL,
  401. NULL);
  402. if (0 == cbAnsiUsed)
  403. {
  404. Status = GetLastError();
  405. } else {
  406. Status = ERROR_SUCCESS;
  407. }
  408. return(Status);
  409. }
  410. ULONG AnsiToUnicode(
  411. LPCSTR pszA,
  412. LPWSTR pszW,
  413. ULONG MaxLen
  414. )
  415. /*++
  416. Routine Description:
  417. Convert Ansi string into its Unicode equivalent
  418. Arguments:
  419. pszA is ansi string to convert
  420. pszW retruns with the string converted to unicode
  421. Return Value:
  422. Error code
  423. --*/
  424. {
  425. ULONG cCharacters;
  426. ULONG Status;
  427. ULONG cbUnicodeUsed;
  428. //
  429. // If input is null then just return the same.
  430. if (pszA == NULL)
  431. {
  432. *pszW = 0;
  433. return(ERROR_SUCCESS);
  434. }
  435. // Convert to Unicode
  436. cbUnicodeUsed = MultiByteToWideChar(CP_ACP,
  437. 0,
  438. pszA,
  439. -1,
  440. pszW,
  441. MaxLen);
  442. if (0 == cbUnicodeUsed)
  443. {
  444. Status = GetLastError();
  445. } else {
  446. Status = ERROR_SUCCESS;
  447. }
  448. return(Status);
  449. }
  450. void CopyString(
  451. PVOID Destination,
  452. PUCHAR *CountedString,
  453. ULONG MaxLenInChar,
  454. BOOLEAN IsAnsi
  455. )
  456. {
  457. PWCHAR DestinationW;
  458. PCHAR DestinationA;
  459. PUSHORT StringPtr = (PUSHORT)(*CountedString);
  460. ULONG Len, MaxLen;
  461. ULONG Status;
  462. Len = *StringPtr++;
  463. *CountedString += (Len + sizeof(USHORT));
  464. if (IsAnsi)
  465. {
  466. DestinationA = (PCHAR)Destination;
  467. DestinationW = (PWCHAR)AllocMemory((Len+1) * sizeof(WCHAR));
  468. if (DestinationW != NULL)
  469. {
  470. wcsncpy(DestinationW,
  471. StringPtr,
  472. Len);
  473. DestinationW[Len] = 0;
  474. Status = UnicodeToAnsi(DestinationW,
  475. DestinationA,
  476. MaxLenInChar);
  477. if (Status != ERROR_SUCCESS)
  478. {
  479. *DestinationA = 0;
  480. }
  481. FreeMemory(DestinationW);
  482. } else {
  483. *DestinationA = 0;
  484. }
  485. } else {
  486. //
  487. // Unicode strings get copied right out of the buffer into the
  488. // return structure
  489. //
  490. DestinationW = (PWCHAR)Destination;
  491. MaxLen = MaxLenInChar * sizeof(WCHAR);
  492. if (Len > MaxLen)
  493. {
  494. Len = MaxLen;
  495. }
  496. wcsncpy(DestinationW,
  497. StringPtr,
  498. Len);
  499. DestinationW[Len] = 0;
  500. }
  501. }
  502. void CopyPortAttributes(
  503. PHBA_PORTATTRIBUTES HbaPortAttributes,
  504. PUCHAR Data,
  505. BOOLEAN IsAnsi
  506. )
  507. {
  508. PHBA_PORTATTRIBUTES HbaPortAttributesA;
  509. //
  510. // We have got our adapter attributes, so copy them
  511. // over to the output buffer
  512. //
  513. if (IsAnsi)
  514. {
  515. HbaPortAttributesA = HbaPortAttributes;
  516. GetDataFromDataBlock(HbaPortAttributesA,
  517. NodeWWN,
  518. HBA_WWN,
  519. Data);
  520. GetDataFromDataBlock(HbaPortAttributesA,
  521. PortWWN,
  522. HBA_WWN,
  523. Data);
  524. GetDataFromDataBlock(HbaPortAttributesA,
  525. PortFcId,
  526. HBA_UINT32,
  527. Data);
  528. GetDataFromDataBlock(HbaPortAttributesA,
  529. PortType,
  530. HBA_UINT32,
  531. Data);
  532. GetDataFromDataBlock(HbaPortAttributesA,
  533. PortState,
  534. HBA_UINT32,
  535. Data);
  536. GetDataFromDataBlock(HbaPortAttributesA,
  537. PortSupportedClassofService,
  538. HBA_UINT32,
  539. Data);
  540. GetDataFromDataBlock(HbaPortAttributesA,
  541. PortSupportedFc4Types,
  542. HBA_FC4TYPES,
  543. Data);
  544. GetDataFromDataBlock(HbaPortAttributesA,
  545. PortActiveFc4Types,
  546. HBA_FC4TYPES,
  547. Data);
  548. GetDataFromDataBlock(HbaPortAttributesA,
  549. PortSupportedSpeed,
  550. HBA_PORTSPEED,
  551. Data);
  552. GetDataFromDataBlock(HbaPortAttributesA,
  553. PortSpeed,
  554. HBA_PORTSPEED,
  555. Data);
  556. GetDataFromDataBlock(HbaPortAttributesA,
  557. PortMaxFrameSize,
  558. HBA_UINT32,
  559. Data);
  560. GetDataFromDataBlock(HbaPortAttributesA,
  561. FabricName,
  562. HBA_WWN,
  563. Data);
  564. GetDataFromDataBlock(HbaPortAttributesA,
  565. NumberofDiscoveredPorts,
  566. HBA_UINT32,
  567. Data);
  568. CopyString(&HbaPortAttributesA->PortSymbolicName,
  569. &Data,
  570. 256,
  571. IsAnsi);
  572. CopyString(&HbaPortAttributesA->OSDeviceName,
  573. &Data,
  574. 256,
  575. IsAnsi);
  576. } else {
  577. GetDataFromDataBlock(HbaPortAttributes,
  578. NodeWWN,
  579. HBA_WWN,
  580. Data);
  581. GetDataFromDataBlock(HbaPortAttributes,
  582. PortWWN,
  583. HBA_WWN,
  584. Data);
  585. GetDataFromDataBlock(HbaPortAttributes,
  586. PortFcId,
  587. HBA_UINT32,
  588. Data);
  589. GetDataFromDataBlock(HbaPortAttributes,
  590. PortType,
  591. HBA_UINT32,
  592. Data);
  593. GetDataFromDataBlock(HbaPortAttributes,
  594. PortState,
  595. HBA_UINT32,
  596. Data);
  597. GetDataFromDataBlock(HbaPortAttributes,
  598. PortSupportedClassofService,
  599. HBA_UINT32,
  600. Data);
  601. GetDataFromDataBlock(HbaPortAttributes,
  602. PortSupportedFc4Types,
  603. HBA_FC4TYPES,
  604. Data);
  605. GetDataFromDataBlock(HbaPortAttributes,
  606. PortActiveFc4Types,
  607. HBA_FC4TYPES,
  608. Data);
  609. GetDataFromDataBlock(HbaPortAttributes,
  610. PortSupportedSpeed,
  611. HBA_PORTSPEED,
  612. Data);
  613. GetDataFromDataBlock(HbaPortAttributes,
  614. PortSpeed,
  615. HBA_PORTSPEED,
  616. Data);
  617. GetDataFromDataBlock(HbaPortAttributes,
  618. PortMaxFrameSize,
  619. HBA_UINT32,
  620. Data);
  621. GetDataFromDataBlock(HbaPortAttributes,
  622. FabricName,
  623. HBA_WWN,
  624. Data);
  625. GetDataFromDataBlock(HbaPortAttributes,
  626. NumberofDiscoveredPorts,
  627. HBA_UINT32,
  628. Data);
  629. CopyString(&HbaPortAttributes->PortSymbolicName,
  630. &Data,
  631. 256,
  632. IsAnsi);
  633. CopyString(&HbaPortAttributes->OSDeviceName,
  634. &Data,
  635. 256,
  636. IsAnsi);
  637. }
  638. }
  639. PVOID AllocMemory(
  640. ULONG SizeNeeded
  641. )
  642. {
  643. PVOID p;
  644. p = LocalAlloc(LPTR,
  645. SizeNeeded);
  646. return(p);
  647. }
  648. void FreeMemory(
  649. PVOID Pointer
  650. )
  651. {
  652. LocalFree(Pointer);
  653. }