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.

1280 lines
37 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. nettype.c
  5. Abstract:
  6. <abstract>
  7. Author:
  8. Jay Thaler (jthaler) 21 Apr 2000
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. //
  13. // Includes
  14. //
  15. #include "pch.h"
  16. #include "logmsg.h"
  17. #include <Winnetwk.h>
  18. #define DBG_NETRESOURCES "MappedDrives"
  19. //
  20. // Strings
  21. //
  22. #define S_MAPPEDDRIVES_POOL_NAME "MappedDrives"
  23. #define S_MAPPEDDRIVES_NAME TEXT("MappedDrives")
  24. #define S_CORPNET_NAME TEXT("Net Printers and Drives")
  25. //
  26. // Constants
  27. //
  28. // none
  29. //
  30. // Macros
  31. //
  32. // none
  33. //
  34. // Types
  35. //
  36. typedef struct {
  37. PCTSTR Pattern;
  38. HASHTABLE_ENUM HashData;
  39. } NETRESOURCE_ENUM, *PNETRESOURCE_ENUM;
  40. typedef struct {
  41. DWORD DisplayType;
  42. DWORD Usage;
  43. CHAR Comment[MAX_PATH];
  44. } NETDRIVE_DATAA, *PNETDRIVE_DATAA;
  45. typedef struct {
  46. DWORD DisplayType;
  47. DWORD Usage;
  48. WCHAR Comment[MAX_PATH];
  49. } NETDRIVE_DATAW, *PNETDRIVE_DATAW;
  50. #ifdef UNICODE
  51. #define NETDRIVE_DATA NETDRIVE_DATAW
  52. #define PNETDRIVE_DATA PNETDRIVE_DATAW
  53. #else
  54. #define NETDRIVE_DATA NETDRIVE_DATAA
  55. #define PNETDRIVE_DATA PNETDRIVE_DATAA
  56. #endif
  57. //
  58. // Globals
  59. //
  60. PMHANDLE g_MappedDrivesPool = NULL;
  61. HASHTABLE g_MappedDrivesTable;
  62. HASHTABLE g_DriveCollisionTable;
  63. MIG_OBJECTTYPEID g_MappedDriveTypeId = 0;
  64. GROWBUFFER g_MappedDriveConversionBuff = INIT_GROWBUFFER;
  65. BOOL g_MappedDrivesMigEnabled = FALSE;
  66. DWORD g_AvailableDrives = 0;
  67. MIG_OPERATIONID g_MappedDriveOp;
  68. BOOL g_DelayNetDrivesOp = FALSE;
  69. //
  70. // Macro expansion list
  71. //
  72. // None
  73. //
  74. // Private function prototypes
  75. //
  76. // None
  77. //
  78. // Macro expansion definition
  79. //
  80. // None
  81. //
  82. // Private prototypes
  83. //
  84. SGMENUMERATIONCALLBACK SgmMappedDrivesCallback;
  85. VCMENUMERATIONCALLBACK VcmMappedDrivesCallback;
  86. TYPE_ENUMFIRSTPHYSICALOBJECT EnumFirstMappedDrive;
  87. TYPE_ENUMNEXTPHYSICALOBJECT EnumNextMappedDrive;
  88. TYPE_ABORTENUMPHYSICALOBJECT AbortEnumMappedDrive;
  89. TYPE_CONVERTOBJECTTOMULTISZ ConvertMappedDriveToMultiSz;
  90. TYPE_CONVERTMULTISZTOOBJECT ConvertMultiSzToMappedDrive;
  91. TYPE_GETNATIVEOBJECTNAME GetNativeMappedDriveName;
  92. TYPE_ACQUIREPHYSICALOBJECT AcquireMappedDrive;
  93. TYPE_RELEASEPHYSICALOBJECT ReleaseMappedDrive;
  94. TYPE_DOESPHYSICALOBJECTEXIST DoesMappedDriveExist;
  95. TYPE_REMOVEPHYSICALOBJECT RemoveMappedDrive;
  96. TYPE_CREATEPHYSICALOBJECT CreateMappedDrive;
  97. TYPE_REPLACEPHYSICALOBJECT ReplaceMappedDrive;
  98. TYPE_CONVERTOBJECTCONTENTTOUNICODE ConvertMappedDriveContentToUnicode;
  99. TYPE_CONVERTOBJECTCONTENTTOANSI ConvertMappedDriveContentToAnsi;
  100. TYPE_FREECONVERTEDOBJECTCONTENT FreeConvertedMappedDriveContent;
  101. OPMFILTERCALLBACK FilterMappedDrive;
  102. //
  103. // Code
  104. //
  105. BOOL
  106. NetDrivesInitialize (
  107. VOID
  108. )
  109. {
  110. g_MappedDrivesTable = HtAllocWithData (sizeof (PNETDRIVE_DATA));
  111. g_MappedDrivesPool = PmCreateNamedPool (S_MAPPEDDRIVES_POOL_NAME);
  112. return (g_MappedDrivesPool != NULL);
  113. }
  114. VOID
  115. NetDrivesTerminate (
  116. VOID
  117. )
  118. {
  119. HASHTABLE_ENUM e;
  120. PNETDRIVE_DATA netdriveData;
  121. GbFree (&g_MappedDriveConversionBuff);
  122. if (g_MappedDrivesTable) {
  123. if (EnumFirstHashTableString (&e, g_MappedDrivesTable)) {
  124. do {
  125. netdriveData = *((PNETDRIVE_DATA *) e.ExtraData);
  126. if (netdriveData) {
  127. PmReleaseMemory (g_MappedDrivesPool, netdriveData);
  128. }
  129. } while (EnumNextHashTableString (&e));
  130. }
  131. HtFree (g_MappedDrivesTable);
  132. g_MappedDrivesTable = NULL;
  133. }
  134. if (g_MappedDrivesPool) {
  135. PmDestroyPool (g_MappedDrivesPool);
  136. g_MappedDrivesPool = NULL;
  137. }
  138. }
  139. BOOL
  140. pLoadMappedDrivesData (
  141. VOID
  142. )
  143. {
  144. DWORD error;
  145. LPNETRESOURCE netBuffer = NULL;
  146. HANDLE netHandle;
  147. DWORD netBufferSize = 16384; // 16K is a good size
  148. DWORD netNumEntries = -1; // enumerate all possible entries
  149. DWORD i;
  150. PNETDRIVE_DATA netDriveData;
  151. MIG_OBJECTSTRINGHANDLE netObject = NULL;
  152. error = WNetOpenEnum (RESOURCE_REMEMBERED, RESOURCETYPE_DISK, 0, netBuffer, &netHandle);
  153. if (error != NO_ERROR) {
  154. return FALSE;
  155. }
  156. netBuffer = PmGetMemory (g_MappedDrivesPool, netBufferSize);
  157. do {
  158. ZeroMemory(netBuffer, netBufferSize);
  159. error = WNetEnumResource (netHandle, &netNumEntries, netBuffer, &netBufferSize);
  160. if (error == ERROR_NO_MORE_ITEMS) {
  161. break;
  162. }
  163. if (error != NO_ERROR) {
  164. PmReleaseMemory (g_MappedDrivesPool, netBuffer);
  165. return FALSE;
  166. }
  167. for (i=0; i<netNumEntries; i++) {
  168. if (netBuffer[i].lpLocalName != NULL) {
  169. netObject = IsmCreateObjectHandle (netBuffer[i].lpLocalName, netBuffer[i].lpRemoteName);
  170. if (netObject) {
  171. netDriveData = (PNETDRIVE_DATA) PmGetMemory (g_MappedDrivesPool, sizeof (NETDRIVE_DATA));
  172. ZeroMemory (netDriveData, sizeof (NETDRIVE_DATA));
  173. netDriveData->DisplayType = netBuffer[i].dwDisplayType;
  174. netDriveData->Usage = netBuffer[i].dwUsage;
  175. if (netBuffer[i].lpComment) {
  176. StringCopyTcharCount (netDriveData->Comment, netBuffer[i].lpComment, MAX_PATH);
  177. }
  178. HtAddStringEx (g_MappedDrivesTable, netObject, &netDriveData, FALSE);
  179. IsmDestroyObjectHandle (netObject);
  180. }
  181. }
  182. }
  183. } while (error != ERROR_NO_MORE_ITEMS);
  184. PmReleaseMemory (g_MappedDrivesPool, netBuffer);
  185. return TRUE;
  186. }
  187. BOOL
  188. WINAPI
  189. NetDrivesEtmInitialize (
  190. IN MIG_PLATFORMTYPEID Platform,
  191. IN PMIG_LOGCALLBACK LogCallback,
  192. IN PVOID Reserved
  193. )
  194. {
  195. TYPE_REGISTER mappedDrivesTypeData;
  196. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  197. pLoadMappedDrivesData ();
  198. ZeroMemory (&mappedDrivesTypeData, sizeof (TYPE_REGISTER));
  199. mappedDrivesTypeData.Priority = PRIORITY_MAPPEDDRIVE;
  200. if (Platform == PLATFORM_SOURCE) {
  201. mappedDrivesTypeData.EnumFirstPhysicalObject = EnumFirstMappedDrive;
  202. mappedDrivesTypeData.EnumNextPhysicalObject = EnumNextMappedDrive;
  203. mappedDrivesTypeData.AbortEnumPhysicalObject = AbortEnumMappedDrive;
  204. mappedDrivesTypeData.ConvertObjectToMultiSz = ConvertMappedDriveToMultiSz;
  205. mappedDrivesTypeData.ConvertMultiSzToObject = ConvertMultiSzToMappedDrive;
  206. mappedDrivesTypeData.GetNativeObjectName = GetNativeMappedDriveName;
  207. mappedDrivesTypeData.AcquirePhysicalObject = AcquireMappedDrive;
  208. mappedDrivesTypeData.ReleasePhysicalObject = ReleaseMappedDrive;
  209. mappedDrivesTypeData.ConvertObjectContentToUnicode = ConvertMappedDriveContentToUnicode;
  210. mappedDrivesTypeData.ConvertObjectContentToAnsi = ConvertMappedDriveContentToAnsi;
  211. mappedDrivesTypeData.FreeConvertedObjectContent = FreeConvertedMappedDriveContent;
  212. g_MappedDriveTypeId = IsmRegisterObjectType (
  213. S_MAPPEDDRIVES_NAME,
  214. TRUE,
  215. FALSE,
  216. &mappedDrivesTypeData
  217. );
  218. } else {
  219. mappedDrivesTypeData.EnumFirstPhysicalObject = EnumFirstMappedDrive;
  220. mappedDrivesTypeData.EnumNextPhysicalObject = EnumNextMappedDrive;
  221. mappedDrivesTypeData.AbortEnumPhysicalObject = AbortEnumMappedDrive;
  222. mappedDrivesTypeData.ConvertObjectToMultiSz = ConvertMappedDriveToMultiSz;
  223. mappedDrivesTypeData.ConvertMultiSzToObject = ConvertMultiSzToMappedDrive;
  224. mappedDrivesTypeData.GetNativeObjectName = GetNativeMappedDriveName;
  225. mappedDrivesTypeData.AcquirePhysicalObject = AcquireMappedDrive;
  226. mappedDrivesTypeData.ReleasePhysicalObject = ReleaseMappedDrive;
  227. mappedDrivesTypeData.DoesPhysicalObjectExist = DoesMappedDriveExist;
  228. mappedDrivesTypeData.RemovePhysicalObject = RemoveMappedDrive;
  229. mappedDrivesTypeData.CreatePhysicalObject = CreateMappedDrive;
  230. mappedDrivesTypeData.ReplacePhysicalObject = ReplaceMappedDrive;
  231. mappedDrivesTypeData.ConvertObjectContentToUnicode = ConvertMappedDriveContentToUnicode;
  232. mappedDrivesTypeData.ConvertObjectContentToAnsi = ConvertMappedDriveContentToAnsi;
  233. mappedDrivesTypeData.FreeConvertedObjectContent = FreeConvertedMappedDriveContent;
  234. g_MappedDriveTypeId = IsmRegisterObjectType (
  235. S_MAPPEDDRIVES_NAME,
  236. TRUE,
  237. FALSE,
  238. &mappedDrivesTypeData
  239. );
  240. }
  241. MYASSERT (g_MappedDriveTypeId);
  242. return TRUE;
  243. }
  244. VOID
  245. WINAPI
  246. NetDrivesEtmNewUserCreated (
  247. IN PCTSTR UserName,
  248. IN PCTSTR DomainName,
  249. IN PCTSTR UserProfileRoot,
  250. IN PSID UserSid
  251. )
  252. {
  253. // a new user was created, the network drives operations need to be delayed
  254. NetDrivesTerminate ();
  255. g_DelayNetDrivesOp = TRUE;
  256. }
  257. BOOL
  258. WINAPI
  259. NetDrivesSgmInitialize (
  260. IN PMIG_LOGCALLBACK LogCallback,
  261. IN PVOID Reserved
  262. )
  263. {
  264. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  265. return TRUE;
  266. }
  267. BOOL
  268. WINAPI
  269. NetDrivesSgmParse (
  270. IN PVOID Reserved
  271. )
  272. {
  273. PCTSTR friendlyName;
  274. friendlyName = GetStringResource (MSG_NET_DRIVES_NAME);
  275. //IsmAddComponentAlias (
  276. // S_MAPPEDDRIVES_NAME,
  277. // MASTERGROUP_SYSTEM,
  278. // friendlyName,
  279. // COMPONENT_NAME,
  280. // FALSE
  281. // );
  282. IsmAddComponentAlias (
  283. S_CORPNET_NAME,
  284. MASTERGROUP_SYSTEM,
  285. friendlyName,
  286. COMPONENT_NAME,
  287. FALSE
  288. );
  289. FreeStringResource (friendlyName);
  290. return TRUE;
  291. }
  292. UINT
  293. SgmMappedDrivesCallback (
  294. IN PCMIG_OBJECTENUMDATA Data,
  295. IN ULONG_PTR CallerArg
  296. )
  297. {
  298. IsmMakeApplyObject (Data->ObjectTypeId, Data->ObjectName);
  299. IsmSetOperationOnObject (Data->ObjectTypeId, Data->ObjectName, g_MappedDriveOp, NULL, NULL);
  300. IsmMakeNonCriticalObject (Data->ObjectTypeId, Data->ObjectName);
  301. return CALLBACK_ENUM_CONTINUE;
  302. }
  303. BOOL
  304. pEnumMappedDriveWorker (
  305. OUT PMIG_TYPEOBJECTENUM EnumPtr,
  306. IN PNETRESOURCE_ENUM MappedDriveEnum
  307. )
  308. {
  309. if (EnumPtr->ObjectNode) {
  310. IsmDestroyObjectString (EnumPtr->ObjectNode);
  311. EnumPtr->ObjectNode = NULL;
  312. }
  313. if (EnumPtr->ObjectLeaf) {
  314. IsmDestroyObjectString (EnumPtr->ObjectLeaf);
  315. EnumPtr->ObjectLeaf = NULL;
  316. }
  317. if (EnumPtr->NativeObjectName) {
  318. PmReleaseMemory (g_MappedDrivesPool, EnumPtr->NativeObjectName);
  319. EnumPtr->NativeObjectName = NULL;
  320. }
  321. do {
  322. EnumPtr->ObjectName = MappedDriveEnum->HashData.String;
  323. if (!ObsPatternMatch (MappedDriveEnum->Pattern, EnumPtr->ObjectName)) {
  324. if (!EnumNextHashTableString (&MappedDriveEnum->HashData)) {
  325. AbortEnumMappedDrive (EnumPtr);
  326. return FALSE;
  327. }
  328. continue;
  329. }
  330. IsmCreateObjectStringsFromHandle (EnumPtr->ObjectName, &EnumPtr->ObjectNode, &EnumPtr->ObjectLeaf);
  331. EnumPtr->NativeObjectName = JoinPathsInPoolEx ((
  332. g_MappedDrivesPool,
  333. EnumPtr->ObjectNode,
  334. TEXT("<=>"),
  335. EnumPtr->ObjectLeaf,
  336. NULL
  337. ));
  338. EnumPtr->Level = 1;
  339. EnumPtr->SubLevel = 0;
  340. EnumPtr->IsLeaf = FALSE;
  341. EnumPtr->IsNode = TRUE;
  342. EnumPtr->Details.DetailsSize = 0;
  343. EnumPtr->Details.DetailsData = NULL;
  344. return TRUE;
  345. } while (TRUE);
  346. }
  347. BOOL
  348. EnumFirstMappedDrive (
  349. IN OUT PMIG_TYPEOBJECTENUM EnumPtr, CALLER_INITIALIZED
  350. IN MIG_OBJECTSTRINGHANDLE Pattern,
  351. IN UINT MaxLevel
  352. )
  353. {
  354. PNETRESOURCE_ENUM netResourceEnum = NULL;
  355. if (!g_MappedDrivesTable) {
  356. AbortEnumMappedDrive (EnumPtr);
  357. return FALSE;
  358. }
  359. netResourceEnum = (PNETRESOURCE_ENUM) PmGetMemory (g_MappedDrivesPool, sizeof (NETRESOURCE_ENUM));
  360. netResourceEnum->Pattern = PmDuplicateString (g_MappedDrivesPool, Pattern);
  361. EnumPtr->EtmHandle = (LONG_PTR) netResourceEnum;
  362. if (EnumFirstHashTableString (&netResourceEnum->HashData, g_MappedDrivesTable)) {
  363. return pEnumMappedDriveWorker (EnumPtr, netResourceEnum);
  364. } else {
  365. AbortEnumMappedDrive (EnumPtr);
  366. return FALSE;
  367. }
  368. }
  369. BOOL
  370. EnumNextMappedDrive (
  371. IN OUT PMIG_TYPEOBJECTENUM EnumPtr
  372. )
  373. {
  374. PNETRESOURCE_ENUM netResourceEnum = NULL;
  375. netResourceEnum = (PNETRESOURCE_ENUM)(EnumPtr->EtmHandle);
  376. if (!netResourceEnum) {
  377. AbortEnumMappedDrive (EnumPtr);
  378. return FALSE;
  379. }
  380. if (EnumNextHashTableString (&netResourceEnum->HashData)) {
  381. return pEnumMappedDriveWorker (EnumPtr, netResourceEnum);
  382. } else {
  383. AbortEnumMappedDrive (EnumPtr);
  384. return FALSE;
  385. }
  386. }
  387. VOID
  388. AbortEnumMappedDrive (
  389. IN OUT PMIG_TYPEOBJECTENUM EnumPtr
  390. )
  391. {
  392. PNETRESOURCE_ENUM netResourceEnum = NULL;
  393. if (EnumPtr->ObjectNode) {
  394. IsmDestroyObjectString (EnumPtr->ObjectNode);
  395. EnumPtr->ObjectNode = NULL;
  396. }
  397. if (EnumPtr->ObjectLeaf) {
  398. IsmDestroyObjectString (EnumPtr->ObjectLeaf);
  399. EnumPtr->ObjectLeaf = NULL;
  400. }
  401. if (EnumPtr->NativeObjectName) {
  402. PmReleaseMemory (g_MappedDrivesPool, EnumPtr->NativeObjectName);
  403. EnumPtr->NativeObjectName = NULL;
  404. }
  405. netResourceEnum = (PNETRESOURCE_ENUM)(EnumPtr->EtmHandle);
  406. if (!netResourceEnum) {
  407. ZeroMemory (EnumPtr, sizeof (MIG_TYPEOBJECTENUM));
  408. return;
  409. }
  410. PmReleaseMemory (g_MappedDrivesPool, netResourceEnum->Pattern);
  411. PmReleaseMemory (g_MappedDrivesPool, netResourceEnum);
  412. ZeroMemory (EnumPtr, sizeof (MIG_TYPEOBJECTENUM));
  413. }
  414. BOOL
  415. AcquireMappedDrive (
  416. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  417. OUT PMIG_CONTENT ObjectContent, CALLER_INITIALIZED
  418. IN MIG_CONTENTTYPE ContentType,
  419. IN UINT MemoryContentLimit
  420. )
  421. {
  422. BOOL result = FALSE;
  423. PNETDRIVE_DATA netdriveData;
  424. if (!ObjectContent) {
  425. return FALSE;
  426. }
  427. // NOTE: Do not zero ObjectContent; some of its members were already set
  428. if (ContentType == CONTENTTYPE_FILE) {
  429. // nobody should request this as a file
  430. DEBUGMSG ((
  431. DBG_WHOOPS,
  432. "Unexpected acquire request for %s: Can't acquire mapped drives as files",
  433. ObjectName
  434. ));
  435. return FALSE;
  436. }
  437. if (HtFindStringEx (g_MappedDrivesTable, ObjectName, (PVOID) &netdriveData, FALSE)) {
  438. //
  439. // Fill in all the content members. We already zeroed the struct,
  440. // so most of the members are taken care of because they are zero.
  441. //
  442. ObjectContent->MemoryContent.ContentBytes = (PBYTE)netdriveData;
  443. ObjectContent->MemoryContent.ContentSize = sizeof(NETDRIVE_DATA);
  444. result = TRUE;
  445. }
  446. return result;
  447. }
  448. BOOL
  449. ReleaseMappedDrive (
  450. IN OUT PMIG_CONTENT ObjectContent
  451. )
  452. {
  453. if (ObjectContent) {
  454. ZeroMemory (ObjectContent, sizeof (MIG_CONTENT));
  455. }
  456. return TRUE;
  457. }
  458. BOOL
  459. DoesMappedDriveExist (
  460. IN MIG_OBJECTSTRINGHANDLE ObjectName
  461. )
  462. {
  463. if (!g_MappedDrivesTable) {
  464. return FALSE;
  465. }
  466. return (HtFindStringEx (g_MappedDrivesTable, ObjectName, NULL, FALSE) != NULL);
  467. }
  468. BOOL
  469. RemoveMappedDrive (
  470. IN MIG_OBJECTSTRINGHANDLE ObjectName
  471. )
  472. {
  473. PCTSTR node;
  474. PCTSTR leaf;
  475. DWORD result = ERROR_NOT_FOUND;
  476. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  477. if (node && (leaf)) {
  478. IsmRecordOperation (JRNOP_DELETE,
  479. g_MappedDriveTypeId,
  480. ObjectName);
  481. // Only set CONNECT_UPDATE_PROFILE when deleting a connection that persists
  482. result = WNetCancelConnection2 ((LPCTSTR)node, CONNECT_UPDATE_PROFILE, TRUE);
  483. if (result != ERROR_SUCCESS) {
  484. DEBUGMSG ((DBG_NETRESOURCES, "Failed to delete existent net resource %s", node));
  485. }
  486. }
  487. IsmDestroyObjectString (node);
  488. IsmDestroyObjectString (leaf);
  489. }
  490. return (result == ERROR_SUCCESS);
  491. }
  492. BOOL
  493. CreateMappedDrive (
  494. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  495. IN PMIG_CONTENT ObjectContent
  496. )
  497. {
  498. PCTSTR node;
  499. PCTSTR leaf;
  500. NETRESOURCE netResource;
  501. BOOL result = ERROR_NOT_FOUND;
  502. PNETDRIVE_DATA netDriveData = NULL;
  503. if (!ObjectContent->ContentInFile) {
  504. if (ObjectContent->MemoryContent.ContentBytes && ObjectContent->MemoryContent.ContentSize) {
  505. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  506. if (node && (leaf)) {
  507. if (g_DelayNetDrivesOp) {
  508. // we need to delay this operation
  509. // record delayed printer create operation
  510. IsmRecordDelayedOperation (
  511. JRNOP_CREATE,
  512. g_MappedDriveTypeId,
  513. ObjectName,
  514. ObjectContent
  515. );
  516. result = TRUE;
  517. } else {
  518. netDriveData = (PNETDRIVE_DATA) PmGetMemory (g_MappedDrivesPool, sizeof (NETDRIVE_DATA));
  519. CopyMemory (netDriveData, ObjectContent->MemoryContent.ContentBytes, sizeof (NETDRIVE_DATA));
  520. ZeroMemory (&netResource, sizeof (NETRESOURCE));
  521. netResource.dwScope = RESOURCE_REMEMBERED;
  522. netResource.dwType = RESOURCETYPE_DISK;
  523. netResource.dwDisplayType = netDriveData->DisplayType;
  524. netResource.dwUsage = netDriveData->Usage;
  525. netResource.lpLocalName = (LPTSTR)node;
  526. netResource.lpRemoteName = (LPTSTR)leaf;
  527. netResource.lpComment = netDriveData->Comment;
  528. netResource.lpProvider = NULL; // Let the API determine the provider
  529. IsmRecordOperation (JRNOP_CREATE,
  530. g_MappedDriveTypeId,
  531. ObjectName);
  532. result = WNetAddConnection2 (&netResource, NULL, NULL, CONNECT_UPDATE_PROFILE);
  533. if (result != ERROR_SUCCESS) {
  534. DEBUGMSG ((DBG_NETRESOURCES, "Failed to add net resource for %s", node));
  535. }
  536. PmReleaseMemory (g_MappedDrivesPool, netDriveData);
  537. }
  538. }
  539. }
  540. }
  541. }
  542. SetLastError (result);
  543. return (result == ERROR_SUCCESS);
  544. }
  545. BOOL
  546. ReplaceMappedDrive (
  547. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  548. IN PMIG_CONTENT ObjectContent
  549. )
  550. {
  551. BOOL result = TRUE;
  552. if (g_DelayNetDrivesOp) {
  553. // we need to delay this operation
  554. // record delayed printer replace operation
  555. IsmRecordDelayedOperation (
  556. JRNOP_REPLACE,
  557. g_MappedDriveTypeId,
  558. ObjectName,
  559. ObjectContent
  560. );
  561. result = TRUE;
  562. } else {
  563. // we are going to delete any existing net share with this name,
  564. // and create a new one
  565. if (DoesMappedDriveExist (ObjectName)) {
  566. result = RemoveMappedDrive (ObjectName);
  567. }
  568. if (result) {
  569. result = CreateMappedDrive (ObjectName, ObjectContent);
  570. }
  571. }
  572. return result;
  573. }
  574. PCTSTR
  575. ConvertMappedDriveToMultiSz (
  576. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  577. IN PMIG_CONTENT ObjectContent
  578. )
  579. {
  580. PCTSTR node, leaf;
  581. PTSTR result = NULL;
  582. BOOL bresult = TRUE;
  583. PNETDRIVE_DATA netDriveData;
  584. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  585. MYASSERT (leaf);
  586. g_MappedDriveConversionBuff.End = 0;
  587. GbCopyQuotedString (&g_MappedDriveConversionBuff, node);
  588. GbCopyQuotedString (&g_MappedDriveConversionBuff, leaf);
  589. MYASSERT (ObjectContent->Details.DetailsSize == 0);
  590. MYASSERT (!ObjectContent->ContentInFile);
  591. MYASSERT (ObjectContent->MemoryContent.ContentSize = sizeof (NETDRIVE_DATA));
  592. if (ObjectContent->MemoryContent.ContentBytes) {
  593. netDriveData = (PNETDRIVE_DATA)ObjectContent->MemoryContent.ContentBytes;
  594. wsprintf (
  595. (PTSTR) GbGrow (&g_MappedDriveConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  596. TEXT("0x%08X"),
  597. netDriveData->DisplayType
  598. );
  599. wsprintf (
  600. (PTSTR) GbGrow (&g_MappedDriveConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  601. TEXT("0x%08X"),
  602. netDriveData->Usage
  603. );
  604. GbCopyQuotedString (&g_MappedDriveConversionBuff, netDriveData->Comment);
  605. } else {
  606. bresult = FALSE;
  607. }
  608. if (bresult) {
  609. GbCopyString (&g_MappedDriveConversionBuff, TEXT(""));
  610. result = IsmGetMemory (g_MappedDriveConversionBuff.End);
  611. CopyMemory (result, g_MappedDriveConversionBuff.Buf, g_MappedDriveConversionBuff.End);
  612. }
  613. g_MappedDriveConversionBuff.End = 0;
  614. IsmDestroyObjectString (node);
  615. INVALID_POINTER (node);
  616. IsmDestroyObjectString (leaf);
  617. INVALID_POINTER (leaf);
  618. }
  619. return result;
  620. }
  621. BOOL
  622. ConvertMultiSzToMappedDrive (
  623. IN PCTSTR ObjectMultiSz,
  624. OUT MIG_OBJECTSTRINGHANDLE *ObjectName,
  625. OUT PMIG_CONTENT ObjectContent CALLER_INITIALIZED OPTIONAL
  626. )
  627. {
  628. MULTISZ_ENUM multiSzEnum;
  629. PCTSTR localName = NULL;
  630. PCTSTR remoteName = NULL;
  631. NETDRIVE_DATA netDriveData;
  632. DWORD dummy;
  633. UINT index;
  634. g_MappedDriveConversionBuff.End = 0;
  635. //
  636. // Parse the multi-sz into the net drive content and details.
  637. // The user may have edited the text (and potentially introduced
  638. // errors).
  639. //
  640. ZeroMemory (&netDriveData, sizeof (NETDRIVE_DATA));
  641. if (EnumFirstMultiSz (&multiSzEnum, ObjectMultiSz)) {
  642. index = 0;
  643. do {
  644. if (index == 0) {
  645. localName = multiSzEnum.CurrentString;
  646. }
  647. if (index == 1) {
  648. remoteName = multiSzEnum.CurrentString;
  649. }
  650. if (index == 2) {
  651. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  652. netDriveData.DisplayType = dummy;
  653. }
  654. if (index == 3) {
  655. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  656. netDriveData.Usage = dummy;
  657. }
  658. if (index == 4) {
  659. if (!StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
  660. StringCopyTcharCount (netDriveData.Comment, multiSzEnum.CurrentString, MAX_PATH);
  661. }
  662. }
  663. index++;
  664. } while (EnumNextMultiSz (&multiSzEnum));
  665. }
  666. if (!localName || !remoteName) {
  667. //
  668. // Bogus data, fail
  669. //
  670. return FALSE;
  671. }
  672. //
  673. // Fill in all the members of the content structure.
  674. //
  675. if (ObjectContent) {
  676. ObjectContent->ContentInFile = FALSE;
  677. ObjectContent->MemoryContent.ContentSize = sizeof (NETDRIVE_DATA);
  678. ObjectContent->MemoryContent.ContentBytes = IsmGetMemory (ObjectContent->MemoryContent.ContentSize);
  679. CopyMemory (
  680. (PBYTE)ObjectContent->MemoryContent.ContentBytes,
  681. &netDriveData,
  682. ObjectContent->MemoryContent.ContentSize
  683. );
  684. ObjectContent->Details.DetailsSize = 0;
  685. ObjectContent->Details.DetailsData = NULL;
  686. }
  687. *ObjectName = IsmCreateObjectHandle (localName, remoteName);
  688. return TRUE;
  689. }
  690. PCTSTR
  691. GetNativeMappedDriveName (
  692. IN MIG_OBJECTSTRINGHANDLE ObjectName
  693. )
  694. {
  695. PCTSTR node = NULL, leaf = NULL;
  696. PTSTR leafPtr = NULL, leafBegin = NULL, nodePtr = NULL;
  697. UINT strSize = 0;
  698. PCTSTR nameMsg;
  699. PCTSTR argArray[3];
  700. PCTSTR result = NULL;
  701. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  702. if (leaf) {
  703. leafPtr = _tcsrchr (leaf, TEXT('\\'));
  704. if (leafPtr) {
  705. *leafPtr = 0;
  706. leafPtr ++;
  707. }
  708. leafBegin = (PTSTR)leaf;
  709. while (*leafBegin == TEXT('\\')) {
  710. leafBegin ++;
  711. }
  712. }
  713. if (node) {
  714. nodePtr = _tcsrchr (node, TEXT('\\'));
  715. if (nodePtr) {
  716. *nodePtr = 0;
  717. }
  718. }
  719. if (leafPtr) {
  720. if (node) {
  721. argArray[0] = (PCTSTR) leafPtr;
  722. argArray[1] = (PCTSTR) leafBegin;
  723. argArray[2] = (PCTSTR) node;
  724. nameMsg = ParseMessageID (MSG_MAPPEDDRIVENAME_1, argArray);
  725. if (nameMsg) {
  726. result = IsmDuplicateString (nameMsg);
  727. FreeStringResource (nameMsg);
  728. }
  729. } else {
  730. argArray[0] = (PCTSTR) leafPtr;
  731. argArray[1] = (PCTSTR) leafBegin;
  732. nameMsg = ParseMessageID (MSG_MAPPEDDRIVENAME_2, argArray);
  733. if (nameMsg) {
  734. result = IsmDuplicateString (nameMsg);
  735. FreeStringResource (nameMsg);
  736. }
  737. }
  738. } else {
  739. if (leafBegin) {
  740. if (node) {
  741. argArray[0] = (PCTSTR) leafBegin;
  742. argArray[1] = (PCTSTR) node;
  743. nameMsg = ParseMessageID (MSG_MAPPEDDRIVENAME_3, argArray);
  744. if (nameMsg) {
  745. result = IsmDuplicateString (nameMsg);
  746. FreeStringResource (nameMsg);
  747. }
  748. } else {
  749. argArray[0] = (PCTSTR) leafBegin;
  750. nameMsg = ParseMessageID (MSG_MAPPEDDRIVENAME_4, argArray);
  751. if (nameMsg) {
  752. result = IsmDuplicateString (nameMsg);
  753. FreeStringResource (nameMsg);
  754. }
  755. }
  756. } else {
  757. if (node) {
  758. argArray[0] = (PCTSTR) node;
  759. nameMsg = ParseMessageID (MSG_MAPPEDDRIVENAME_5, argArray);
  760. if (nameMsg) {
  761. result = IsmDuplicateString (nameMsg);
  762. FreeStringResource (nameMsg);
  763. }
  764. }
  765. }
  766. }
  767. IsmDestroyObjectString (node);
  768. IsmDestroyObjectString (leaf);
  769. }
  770. return result;
  771. }
  772. PMIG_CONTENT
  773. ConvertMappedDriveContentToUnicode (
  774. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  775. IN PMIG_CONTENT ObjectContent
  776. )
  777. {
  778. PMIG_CONTENT result = NULL;
  779. if (!ObjectContent) {
  780. return result;
  781. }
  782. if (ObjectContent->ContentInFile) {
  783. return result;
  784. }
  785. result = IsmGetMemory (sizeof (MIG_CONTENT));
  786. if (result) {
  787. CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
  788. if ((ObjectContent->MemoryContent.ContentSize != 0) &&
  789. (ObjectContent->MemoryContent.ContentBytes != NULL)
  790. ) {
  791. // convert Mapped Drive content
  792. result->MemoryContent.ContentBytes = IsmGetMemory (sizeof (NETDRIVE_DATAW));
  793. if (result->MemoryContent.ContentBytes) {
  794. ((PNETDRIVE_DATAW)result->MemoryContent.ContentBytes)->DisplayType =
  795. ((PNETDRIVE_DATAA)ObjectContent->MemoryContent.ContentBytes)->DisplayType;
  796. ((PNETDRIVE_DATAW)result->MemoryContent.ContentBytes)->Usage =
  797. ((PNETDRIVE_DATAA)ObjectContent->MemoryContent.ContentBytes)->Usage;
  798. DirectDbcsToUnicodeN (
  799. ((PNETDRIVE_DATAW)result->MemoryContent.ContentBytes)->Comment,
  800. ((PNETDRIVE_DATAA)ObjectContent->MemoryContent.ContentBytes)->Comment,
  801. MAX_PATH
  802. );
  803. result->MemoryContent.ContentSize = sizeof (NETDRIVE_DATAW);
  804. }
  805. }
  806. }
  807. return result;
  808. }
  809. PMIG_CONTENT
  810. ConvertMappedDriveContentToAnsi (
  811. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  812. IN PMIG_CONTENT ObjectContent
  813. )
  814. {
  815. PMIG_CONTENT result = NULL;
  816. if (!ObjectContent) {
  817. return result;
  818. }
  819. if (ObjectContent->ContentInFile) {
  820. return result;
  821. }
  822. result = IsmGetMemory (sizeof (MIG_CONTENT));
  823. if (result) {
  824. CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
  825. if ((ObjectContent->MemoryContent.ContentSize != 0) &&
  826. (ObjectContent->MemoryContent.ContentBytes != NULL)
  827. ) {
  828. // convert Mapped Drive content
  829. result->MemoryContent.ContentBytes = IsmGetMemory (sizeof (NETDRIVE_DATAA));
  830. if (result->MemoryContent.ContentBytes) {
  831. ((PNETDRIVE_DATAA)result->MemoryContent.ContentBytes)->DisplayType =
  832. ((PNETDRIVE_DATAW)ObjectContent->MemoryContent.ContentBytes)->DisplayType;
  833. ((PNETDRIVE_DATAA)result->MemoryContent.ContentBytes)->Usage =
  834. ((PNETDRIVE_DATAW)ObjectContent->MemoryContent.ContentBytes)->Usage;
  835. DirectUnicodeToDbcsN (
  836. ((PNETDRIVE_DATAA)result->MemoryContent.ContentBytes)->Comment,
  837. ((PNETDRIVE_DATAW)ObjectContent->MemoryContent.ContentBytes)->Comment,
  838. MAX_PATH
  839. );
  840. result->MemoryContent.ContentSize = sizeof (NETDRIVE_DATAA);
  841. }
  842. }
  843. }
  844. return result;
  845. }
  846. BOOL
  847. FreeConvertedMappedDriveContent (
  848. IN PMIG_CONTENT ObjectContent
  849. )
  850. {
  851. if (!ObjectContent) {
  852. return TRUE;
  853. }
  854. if (ObjectContent->MemoryContent.ContentBytes) {
  855. IsmReleaseMemory (ObjectContent->MemoryContent.ContentBytes);
  856. }
  857. IsmReleaseMemory (ObjectContent);
  858. return TRUE;
  859. }
  860. BOOL
  861. WINAPI
  862. NetDrivesVcmInitialize (
  863. IN PMIG_LOGCALLBACK LogCallback,
  864. IN PVOID Reserved
  865. )
  866. {
  867. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  868. return TRUE;
  869. }
  870. BOOL
  871. WINAPI
  872. NetDrivesVcmParse (
  873. IN PVOID Reserved
  874. )
  875. {
  876. return NetDrivesSgmParse (Reserved);
  877. }
  878. UINT
  879. VcmMappedDrivesCallback (
  880. IN PCMIG_OBJECTENUMDATA Data,
  881. IN ULONG_PTR CallerArg
  882. )
  883. {
  884. IsmMakePersistentObject (Data->ObjectTypeId, Data->ObjectName);
  885. return CALLBACK_ENUM_CONTINUE;
  886. }
  887. BOOL
  888. pCommonNetDrivesQueueEnumeration (
  889. IN BOOL VcmMode
  890. )
  891. {
  892. ENCODEDSTRHANDLE pattern;
  893. if (!IsmIsComponentSelected (S_MAPPEDDRIVES_NAME, 0) &&
  894. !IsmIsComponentSelected (S_CORPNET_NAME, 0)
  895. ) {
  896. g_MappedDrivesMigEnabled = FALSE;
  897. return TRUE;
  898. }
  899. g_MappedDrivesMigEnabled = TRUE;
  900. g_MappedDriveOp = IsmRegisterOperation (S_OPERATION_DRIVEMAP_FIXCONTENT, TRUE);
  901. pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, TRUE);
  902. IsmQueueEnumeration (
  903. g_MappedDriveTypeId,
  904. pattern,
  905. VcmMode ? VcmMappedDrivesCallback : SgmMappedDrivesCallback,
  906. (ULONG_PTR) 0,
  907. S_MAPPEDDRIVES_NAME
  908. );
  909. IsmDestroyObjectHandle (pattern);
  910. return TRUE;
  911. }
  912. BOOL
  913. WINAPI
  914. NetDrivesSgmQueueEnumeration (
  915. IN PVOID Reserved
  916. )
  917. {
  918. return pCommonNetDrivesQueueEnumeration (FALSE);
  919. }
  920. BOOL
  921. WINAPI
  922. NetDrivesVcmQueueEnumeration (
  923. IN PVOID Reserved
  924. )
  925. {
  926. return pCommonNetDrivesQueueEnumeration (TRUE);
  927. }
  928. BOOL
  929. WINAPI
  930. NetDrivesCsmInitialize (
  931. IN PMIG_LOGCALLBACK LogCallback,
  932. IN PVOID Reserved
  933. )
  934. {
  935. g_AvailableDrives = GetLogicalDrives ();
  936. g_DriveCollisionTable = HtAllocWithData (sizeof (TCHAR));
  937. return TRUE;
  938. }
  939. DWORD
  940. pConvertDriveToBit (
  941. PCTSTR driveString
  942. )
  943. {
  944. DWORD bit = 0;
  945. TCHAR driveLetter;
  946. if (driveString && *driveString) {
  947. driveLetter = (TCHAR)_totlower (*driveString);
  948. if (driveLetter >= TEXT('a') && driveLetter <= TEXT('z')) {
  949. bit = 0x1 << (driveLetter - TEXT('a'));
  950. }
  951. }
  952. return bit;
  953. }
  954. BOOL
  955. pReserveAvailableDrive (
  956. TCHAR *driveLetter
  957. )
  958. {
  959. DWORD bit;
  960. BOOL success = FALSE;
  961. // Start at bit 2 so we only map to C: or higher
  962. for (bit = 2; bit < 26; bit++) {
  963. if (!(g_AvailableDrives & (1 << bit))) {
  964. success = TRUE;
  965. g_AvailableDrives |= (1 << bit);
  966. *driveLetter = (TCHAR)(TEXT('a') + bit);
  967. break;
  968. }
  969. }
  970. return success;
  971. }
  972. BOOL
  973. WINAPI
  974. NetDrivesCsmExecute (
  975. VOID
  976. )
  977. {
  978. GROWBUFFER collisions = INIT_GROWBUFFER;
  979. DWORD driveBit;
  980. TCHAR existingPath[MAX_PATH + 1];
  981. MULTISZ_ENUM e;
  982. TCHAR freeDrive;
  983. DWORD bufferSize;
  984. MIG_OBJECTSTRINGHANDLE pattern;
  985. MIG_OBJECT_ENUM objectEnum;
  986. PCTSTR node;
  987. PCTSTR leaf;
  988. DWORD result;
  989. // First, enumerate all the mapped drives and look for collisions
  990. pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, TRUE); // *,*
  991. if (IsmEnumFirstSourceObject (&objectEnum, g_MappedDriveTypeId, pattern)) {
  992. do {
  993. IsmCreateObjectStringsFromHandle (objectEnum.ObjectName, &node, &leaf);
  994. // Leaf is the remote name.
  995. driveBit = pConvertDriveToBit (node);
  996. if (g_AvailableDrives & driveBit) {
  997. // Something is already there. Is it the same thing?
  998. ZeroMemory (existingPath, MAX_PATH + 1);
  999. bufferSize = MAX_PATH + 1;
  1000. result = WNetGetConnection (node, existingPath, &bufferSize);
  1001. if (result != NO_ERROR) {
  1002. // this might be a fixed drive
  1003. GbMultiSzAppend (&collisions, node);
  1004. } else {
  1005. if (!StringIMatch (existingPath, leaf)) {
  1006. // Whoops, we have a collision. Save it for later
  1007. GbMultiSzAppend (&collisions, node);
  1008. }
  1009. }
  1010. } else {
  1011. // It's free, so let's reserve it.
  1012. g_AvailableDrives |= driveBit;
  1013. }
  1014. IsmDestroyObjectString (node);
  1015. IsmDestroyObjectString (leaf);
  1016. } while (IsmEnumNextObject (&objectEnum));
  1017. }
  1018. IsmDestroyObjectHandle (pattern);
  1019. INVALID_POINTER (pattern);
  1020. // Enumerate collided mappings and find new destinations
  1021. if (EnumFirstMultiSz (&e, (PCTSTR) collisions.Buf)) {
  1022. do {
  1023. if (pReserveAvailableDrive (&freeDrive)) {
  1024. HtAddStringEx (g_DriveCollisionTable, e.CurrentString, &freeDrive, FALSE);
  1025. }
  1026. } while (EnumNextMultiSz (&e));
  1027. }
  1028. GbFree (&collisions);
  1029. return TRUE;
  1030. }
  1031. BOOL
  1032. WINAPI
  1033. NetDrivesOpmInitialize (
  1034. IN PMIG_LOGCALLBACK LogCallback,
  1035. IN PVOID Reserved
  1036. )
  1037. {
  1038. //
  1039. // Get attribute and operation types
  1040. //
  1041. g_MappedDriveOp = IsmRegisterOperation (S_OPERATION_DRIVEMAP_FIXCONTENT, TRUE);
  1042. //
  1043. // Register operation callbacks
  1044. //
  1045. IsmRegisterOperationFilterCallback (g_MappedDriveOp, FilterMappedDrive, TRUE, TRUE, FALSE);
  1046. return TRUE;
  1047. }
  1048. BOOL
  1049. WINAPI
  1050. FilterMappedDrive (
  1051. IN PCMIG_FILTERINPUT InputData,
  1052. OUT PMIG_FILTEROUTPUT OutputData,
  1053. IN BOOL NoRestoreObject,
  1054. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  1055. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  1056. )
  1057. {
  1058. PTSTR node = NULL;
  1059. PCTSTR leaf = NULL;
  1060. MIG_OBJECTSTRINGHANDLE destHandle;
  1061. TCHAR driveLetter;
  1062. try {
  1063. if ((InputData->CurrentObject.ObjectTypeId & (~PLATFORM_MASK)) != g_MappedDriveTypeId) {
  1064. DEBUGMSG ((DBG_ERROR, "Unexpected object type in FilterMappedDrive"));
  1065. __leave;
  1066. }
  1067. if (!IsmCreateObjectStringsFromHandle (
  1068. InputData->OriginalObject.ObjectName,
  1069. &node,
  1070. &leaf
  1071. )) {
  1072. __leave;
  1073. }
  1074. MYASSERT (node);
  1075. MYASSERT (leaf);
  1076. if (node) {
  1077. if (HtFindStringEx (g_DriveCollisionTable, node, &driveLetter, FALSE)) {
  1078. node[0] = driveLetter;
  1079. }
  1080. destHandle = IsmCreateObjectHandle (node, leaf);
  1081. if (destHandle) {
  1082. OutputData->NewObject.ObjectName = destHandle;
  1083. }
  1084. }
  1085. }
  1086. __finally {
  1087. IsmDestroyObjectString (node);
  1088. IsmDestroyObjectString (leaf);
  1089. }
  1090. return TRUE;
  1091. }