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.

1376 lines
38 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. netshares.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. #include <Lm.h>
  19. #include <Lmshare.h>
  20. #define DBG_NETSHARES "NetShares"
  21. //
  22. // Strings
  23. //
  24. #define S_NETSHARES_NAME TEXT("NetShares")
  25. //
  26. // Constants
  27. //
  28. /* These flags are relevant for share-level security on VSERVER
  29. * When operating with user-level security, use SHI50F_FULL - the actual
  30. * access rights are determined by the NetAccess APIs.
  31. */
  32. #define SHI50F_RDONLY 0x0001
  33. #define SHI50F_FULL 0x0002
  34. #define SHI50F_ACCESSMASK (SHI50F_RDONLY|SHI50F_FULL)
  35. /* The share is restored on system startup */
  36. #define SHI50F_PERSIST 0x0100
  37. /* The share is not normally visible */
  38. #define SHI50F_SYSTEM 0x0200
  39. //
  40. // Win9x migration net share flag, used to distinguish user-level security and
  41. // password-level security. When it is specified, user-level
  42. // security is enabled, and NetShares\<share>\ACL\<list> exists.
  43. //
  44. #define SHI50F_ACLS 0x1000
  45. //
  46. // Flags that help determine when custom access is enabled
  47. //
  48. #define READ_ACCESS_FLAGS 0x0081
  49. #define READ_ACCESS_MASK 0x7fff
  50. #define FULL_ACCESS_FLAGS 0x00b7
  51. #define FULL_ACCESS_MASK 0x7fff
  52. #define INDEXLOCAL 0
  53. #define INDEXREMOTE 1
  54. //
  55. // Macros
  56. //
  57. // None
  58. //
  59. // Types
  60. //
  61. typedef struct {
  62. PCTSTR Pattern;
  63. HASHTABLE_ENUM HashData;
  64. } NETSHARE_ENUM, *PNETSHARE_ENUM;
  65. typedef struct {
  66. CHAR sharePath[MAX_PATH + 1];
  67. } NETSHARE_DATAA, *PNETSHARE_DATAA;
  68. typedef struct {
  69. WCHAR sharePath[MAX_PATH + 1];
  70. } NETSHARE_DATAW, *PNETSHARE_DATAW;
  71. #ifdef UNICODE
  72. #define NETSHARE_DATA NETSHARE_DATAW
  73. #define PNETSHARE_DATA PNETSHARE_DATAW
  74. #else
  75. #define NETSHARE_DATA NETSHARE_DATAA
  76. #define PNETSHARE_DATA PNETSHARE_DATAA
  77. #endif
  78. //
  79. // types not defined by public headers
  80. //
  81. typedef NET_API_STATUS (* ScanNetShareEnumNT) (
  82. LMSTR servername,
  83. DWORD level,
  84. PBYTE *bufptr,
  85. DWORD prefmaxlen,
  86. PDWORD entriesread,
  87. PDWORD totalentries,
  88. PDWORD resume_handle
  89. );
  90. typedef NET_API_STATUS (* ScanNetShareEnum9x) (
  91. const char * servername,
  92. short level,
  93. char * bufptr,
  94. unsigned short prefmaxlen,
  95. unsigned short * entriesread,
  96. unsigned short * totalentries
  97. );
  98. typedef NET_API_STATUS (* ScanNetApiBufferFreeNT) ( void *);
  99. typedef NET_API_STATUS (* ScanNetAccessEnum9x) (
  100. const char * pszServer,
  101. char * pszBasePath,
  102. short fsRecursive,
  103. short sLevel,
  104. char * pbBuffer,
  105. unsigned short cbBuffer,
  106. unsigned short * pcEntriesRead,
  107. unsigned short * pcTotalAvail
  108. );
  109. #pragma pack(push)
  110. #pragma pack(1) /* Assume byte packing throughout */
  111. struct _share_info_50 {
  112. char shi50_netname[LM20_NNLEN+1];
  113. unsigned char shi50_type;
  114. unsigned short shi50_flags;
  115. char * shi50_remark;
  116. char * shi50_path;
  117. char shi50_rw_password[SHPWLEN+1];
  118. char shi50_ro_password[SHPWLEN+1];
  119. };
  120. struct access_list_2
  121. {
  122. char * acl2_ugname;
  123. unsigned short acl2_access;
  124. }; /* access_list_2 */
  125. struct access_info_2
  126. {
  127. char * acc2_resource_name;
  128. short acc2_attr;
  129. unsigned short acc2_count;
  130. }; /* access_info_2 */
  131. #pragma pack(pop)
  132. //
  133. // netapi functions
  134. //
  135. typedef NET_API_STATUS(WINAPI NETSHAREADDW)(
  136. IN PWSTR servername,
  137. IN DWORD level,
  138. IN PBYTE buf,
  139. OUT PDWORD parm_err
  140. );
  141. typedef NETSHAREADDW *PNETSHAREADDW;
  142. typedef NET_API_STATUS(WINAPI NETSHAREDELW)(
  143. IN PWSTR servername,
  144. IN PWSTR netname,
  145. IN DWORD reserved
  146. );
  147. typedef NETSHAREDELW *PNETSHAREDELW;
  148. //
  149. // Globals
  150. //
  151. PMHANDLE g_NetSharesPool = NULL;
  152. PMHANDLE g_PathPool = NULL;
  153. HASHTABLE g_NetSharesTable;
  154. MIG_OBJECTTYPEID g_NetShareTypeId = 0;
  155. static BOOL g_IsWin9x = FALSE;
  156. GROWBUFFER g_NetShareConversionBuff = INIT_GROWBUFFER;
  157. BOOL g_NetSharesMigEnabled = FALSE;
  158. //
  159. // Macro expansion list
  160. //
  161. // None
  162. //
  163. // Private function prototypes
  164. //
  165. // None
  166. //
  167. // Macro expansion definition
  168. //
  169. // None
  170. //
  171. // Private prototypes
  172. //
  173. TYPE_ENUMFIRSTPHYSICALOBJECT EnumFirstNetShare;
  174. TYPE_ENUMNEXTPHYSICALOBJECT EnumNextNetShare;
  175. TYPE_ABORTENUMPHYSICALOBJECT AbortEnumNetShare;
  176. TYPE_CONVERTOBJECTTOMULTISZ ConvertNetShareToMultiSz;
  177. TYPE_CONVERTMULTISZTOOBJECT ConvertMultiSzToNetShare;
  178. TYPE_GETNATIVEOBJECTNAME GetNativeNetShareName;
  179. TYPE_ACQUIREPHYSICALOBJECT AcquireNetShare;
  180. TYPE_RELEASEPHYSICALOBJECT ReleaseNetShare;
  181. TYPE_DOESPHYSICALOBJECTEXIST DoesNetShareExist;
  182. TYPE_REMOVEPHYSICALOBJECT RemoveNetShare;
  183. TYPE_CREATEPHYSICALOBJECT CreateNetShare;
  184. TYPE_CONVERTOBJECTCONTENTTOUNICODE ConvertNetShareContentToUnicode;
  185. TYPE_CONVERTOBJECTCONTENTTOANSI ConvertNetShareContentToAnsi;
  186. TYPE_FREECONVERTEDOBJECTCONTENT FreeConvertedNetShareContent;
  187. //
  188. // netapi functions
  189. //
  190. PNETSHAREADDW g_NetShareAddW = NULL;
  191. PNETSHAREDELW g_NetShareDelW = NULL;
  192. //
  193. // Code
  194. //
  195. BOOL
  196. NetSharesInitialize (
  197. VOID
  198. )
  199. {
  200. OSVERSIONINFO versionInfo;
  201. ZeroMemory (&versionInfo, sizeof (OSVERSIONINFO));
  202. versionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
  203. if (!GetVersionEx (&versionInfo)) {
  204. return FALSE;
  205. }
  206. g_IsWin9x = (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
  207. g_PathPool = PmCreateNamedPool ("NetShares Paths");
  208. g_NetSharesTable = HtAllocWithData (sizeof (PNETSHARE_DATA));
  209. g_NetSharesPool = PmCreateNamedPool ("NetShares");
  210. return TRUE;
  211. }
  212. VOID
  213. NetSharesTerminate (
  214. VOID
  215. )
  216. {
  217. HASHTABLE_ENUM e;
  218. PNETSHARE_DATA netshareData;
  219. if (g_NetSharesTable) {
  220. if (EnumFirstHashTableString (&e, g_NetSharesTable)) {
  221. do {
  222. netshareData = *((PNETSHARE_DATA *) e.ExtraData);
  223. if (netshareData) {
  224. PmReleaseMemory (g_NetSharesPool, netshareData);
  225. }
  226. } while (EnumNextHashTableString (&e));
  227. }
  228. HtFree (g_NetSharesTable);
  229. g_NetSharesTable = NULL;
  230. }
  231. PmDestroyPool (g_NetSharesPool);
  232. g_NetSharesPool = NULL;
  233. PmDestroyPool (g_PathPool);
  234. g_PathPool = NULL;
  235. }
  236. BOOL
  237. pLoadNetSharesData (
  238. VOID
  239. )
  240. {
  241. DWORD error;
  242. PBYTE netBuffer = NULL;
  243. CHAR netBuf9x[16384]; // static because NetShareEnum is unreliable
  244. DWORD netNumEntries = 0;
  245. DWORD totalEntries = 0;
  246. DWORD i;
  247. DWORD j;
  248. DWORD level;
  249. HINSTANCE hInst;
  250. PCTSTR name = NULL;
  251. PCTSTR path = NULL;
  252. PNETSHARE_DATA netshareData;
  253. //
  254. // Get the net share info from the machine
  255. //
  256. level = (g_IsWin9x ? 50 : 502);
  257. hInst = LoadLibraryA (g_IsWin9x ? "svrapi.dll" : "netapi32.dll");
  258. if (hInst == 0) {
  259. SetLastError (ERROR_INVALID_DLL);
  260. return FALSE;
  261. }
  262. if (g_IsWin9x) {
  263. struct _share_info_50 *tmpBuf;
  264. ScanNetShareEnum9x pNetShareEnum9x = NULL;
  265. ScanNetAccessEnum9x pNetAccessEnum9x = NULL;
  266. pNetShareEnum9x = (ScanNetShareEnum9x) GetProcAddress (hInst, "NetShareEnum");
  267. if (pNetShareEnum9x == NULL) {
  268. SetLastError (ERROR_INVALID_DLL);
  269. return FALSE;
  270. }
  271. pNetAccessEnum9x = (ScanNetAccessEnum9x) GetProcAddress (hInst, "NetAccessEnum");
  272. if (pNetAccessEnum9x == NULL) {
  273. SetLastError (ERROR_INVALID_DLL);
  274. return FALSE;
  275. }
  276. error = (*pNetShareEnum9x)(NULL,
  277. (short)level,
  278. netBuf9x,
  279. sizeof (netBuf9x),
  280. (USHORT *)&netNumEntries,
  281. (USHORT *)&totalEntries);
  282. if ((error == ERROR_SUCCESS) || (error == ERROR_MORE_DATA)) {
  283. for (i = 0; i < netNumEntries; i++) {
  284. DWORD dwPerms = 0;
  285. tmpBuf = (struct _share_info_50 *)(netBuf9x + (i * sizeof(struct _share_info_50)));
  286. // Require share to be a user-defined, persistent disk share
  287. if ((tmpBuf->shi50_flags & SHI50F_SYSTEM) ||
  288. !(tmpBuf->shi50_flags & SHI50F_PERSIST) ||
  289. tmpBuf->shi50_type != STYPE_DISKTREE ) {
  290. continue;
  291. }
  292. if (tmpBuf->shi50_flags & SHI50F_RDONLY) {
  293. dwPerms = ACCESS_READ;
  294. } else if (tmpBuf->shi50_flags & SHI50F_FULL) {
  295. dwPerms = ACCESS_ALL;
  296. }
  297. // JTJTJT: Also store dwPerms
  298. //
  299. // Process custom access permissions
  300. //
  301. if ((tmpBuf->shi50_flags & SHI50F_ACCESSMASK) ==
  302. SHI50F_ACCESSMASK) {
  303. static CHAR AccessInfoBuf[16384];
  304. WORD wItemsAvail, wItemsRead;
  305. error = (*pNetAccessEnum9x) (NULL,
  306. tmpBuf->shi50_path,
  307. 0,
  308. 2,
  309. AccessInfoBuf,
  310. sizeof (AccessInfoBuf),
  311. &wItemsRead,
  312. &wItemsAvail
  313. );
  314. if (error != NERR_ACFNotLoaded) {
  315. BOOL LostCustomAccess = FALSE;
  316. if (error == ERROR_SUCCESS) {
  317. struct access_info_2 *pai;
  318. struct access_list_2 *pal;
  319. pai = (struct access_info_2 *) AccessInfoBuf;
  320. pal = (struct access_list_2 *) (&pai[1]);
  321. for (j = 0 ; j < pai->acc2_count ; j++) {
  322. #if 0
  323. // turn off custom access support
  324. // implementation is incomplete
  325. if (pal->acl2_access & READ_ACCESS_FLAGS) {
  326. Win32Printf (h, " %s, read\r\n",
  327. pal->acl2_ugname);
  328. } else if(pal->acl2_access & FULL_ACCESS_FLAGS) {
  329. Win32Printf (h, " %s, full\r\n",
  330. pal->acl2_ugname);
  331. } else
  332. #endif
  333. LostCustomAccess = TRUE;
  334. pal++;
  335. }
  336. if (LostCustomAccess) {
  337. DEBUGMSG ((DBG_NETSHARES, "Share %s not migrated.", tmpBuf->shi50_netname));
  338. continue;
  339. }
  340. tmpBuf->shi50_flags |= SHI50F_ACLS;
  341. } else if (error != ERROR_SUCCESS) {
  342. return FALSE;
  343. }
  344. }
  345. }
  346. if (!(tmpBuf->shi50_flags & SHI50F_ACLS) &&
  347. (tmpBuf->shi50_rw_password[0] ||
  348. tmpBuf->shi50_ro_password[0])) {
  349. // IDS_SHARE_PASSWORD_NOT_MIGRATED, tmpBuf->shi50_netname
  350. DEBUGMSG ((DBG_NETSHARES, "Share %s not migrated.", tmpBuf->shi50_netname));
  351. continue;
  352. }
  353. // everything looks OK, let's add this entry
  354. name = ConvertAtoT (tmpBuf->shi50_netname);
  355. path = ConvertAtoT (tmpBuf->shi50_path);
  356. netshareData = (PNETSHARE_DATA) PmGetMemory (g_NetSharesPool, sizeof (NETSHARE_DATA));
  357. ZeroMemory (netshareData, sizeof (NETSHARE_DATA));
  358. StringCopy (netshareData->sharePath, path);
  359. HtAddStringEx (g_NetSharesTable, name, &netshareData, FALSE);
  360. FreeAtoT (name);
  361. INVALID_POINTER (name);
  362. FreeAtoT (path);
  363. INVALID_POINTER (path);
  364. }
  365. } else if (error == NERR_ServerNotStarted) {
  366. error = ERROR_SUCCESS;
  367. }
  368. } else {
  369. ScanNetShareEnumNT pNetShareEnum = NULL;
  370. SHARE_INFO_502* tmpBuf = NULL;
  371. pNetShareEnum = (ScanNetShareEnumNT) GetProcAddress(hInst, "NetShareEnum");
  372. if (pNetShareEnum == NULL) {
  373. SetLastError (ERROR_INVALID_DLL);
  374. return FALSE;
  375. }
  376. //
  377. // Call the NetShareEnum function to list the
  378. // shares, specifying information level 502.
  379. //
  380. error = (*pNetShareEnum)(NULL,
  381. level,
  382. (BYTE **) &netBuffer,
  383. MAX_PREFERRED_LENGTH,
  384. &netNumEntries,
  385. &totalEntries,
  386. NULL);
  387. //
  388. // Loop through the entries; process errors.
  389. //
  390. if (error == ERROR_SUCCESS) {
  391. if ((tmpBuf = (SHARE_INFO_502 *)netBuffer) != NULL) {
  392. for (i = 0; (i < netNumEntries); i++) {
  393. if (!(tmpBuf->shi502_type & STYPE_SPECIAL)) {
  394. name = ConvertWtoT (tmpBuf->shi502_netname);
  395. path = ConvertWtoT (tmpBuf->shi502_path);
  396. netshareData = (PNETSHARE_DATA) PmGetMemory (g_NetSharesPool, sizeof (NETSHARE_DATA));
  397. ZeroMemory (netshareData, sizeof (NETSHARE_DATA));
  398. StringCopy (netshareData->sharePath, path);
  399. HtAddStringEx (g_NetSharesTable, name, &netshareData, FALSE);
  400. // JTJTJT: also store tmpBuf->shi502_permissions, tmpBuf->shi502_remark));
  401. FreeWtoT (name);
  402. INVALID_POINTER (name);
  403. FreeWtoT (path);
  404. INVALID_POINTER (path);
  405. }
  406. tmpBuf++;
  407. }
  408. }
  409. } else {
  410. //SetLastError (IDS_CANNOT_ENUM_NETSHARES);
  411. return FALSE;
  412. }
  413. if (netBuffer != NULL) {
  414. ScanNetApiBufferFreeNT pNetApiBufferFree = NULL;
  415. pNetApiBufferFree = (ScanNetApiBufferFreeNT) GetProcAddress (hInst, "NetApiBufferFree");
  416. if (pNetApiBufferFree != NULL)
  417. (*pNetApiBufferFree) (netBuffer);
  418. }
  419. }
  420. return TRUE;
  421. }
  422. BOOL
  423. pLoadNetEntries (
  424. VOID
  425. )
  426. {
  427. HMODULE netDll = NULL;
  428. BOOL result = FALSE;
  429. //
  430. // Get the net api entry points. Sometimes networking isn't installed.
  431. //
  432. __try {
  433. netDll = LoadLibrary (TEXT("NETAPI32.DLL"));
  434. }
  435. __except (EXCEPTION_EXECUTE_HANDLER) {
  436. netDll = NULL;
  437. }
  438. if (netDll) {
  439. g_NetShareAddW = (PNETSHAREADDW) GetProcAddress (netDll, "NetShareAdd");
  440. g_NetShareDelW = (PNETSHAREDELW) GetProcAddress (netDll, "NetShareDel");
  441. if (g_NetShareAddW && g_NetShareDelW) {
  442. result = TRUE;
  443. } else {
  444. result = FALSE;
  445. DEBUGMSG ((DBG_NETSHARES, "Not all NETAPI32 entry points were found."));
  446. }
  447. } else {
  448. DEBUGMSG ((DBG_NETSHARES, "NETAPI32 is not installed on this computer."));
  449. }
  450. return result;
  451. }
  452. BOOL
  453. WINAPI
  454. NetSharesEtmInitialize (
  455. IN MIG_PLATFORMTYPEID Platform,
  456. IN PMIG_LOGCALLBACK LogCallback,
  457. IN PVOID Reserved
  458. )
  459. {
  460. TYPE_REGISTER netSharesTypeData;
  461. //
  462. // We need to register our type callback functions. Types allow us to
  463. // abstract net shares into generalized objects. The engine can perform
  464. // global operations with this abstraction (such as undo or compare), and
  465. // modules can access net shares without knowing the complexities of
  466. // OS-specific APIs, bugs & workarounds, storage formats, etc. Script
  467. // modules can implement script capabilities that control net shares
  468. // without actually inventing special net share syntaxes (or even knowing
  469. // about net shares).
  470. //
  471. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  472. pLoadNetSharesData ();
  473. ZeroMemory (&netSharesTypeData, sizeof (TYPE_REGISTER));
  474. if (Platform == PLATFORM_SOURCE) {
  475. netSharesTypeData.EnumFirstPhysicalObject = EnumFirstNetShare;
  476. netSharesTypeData.EnumNextPhysicalObject = EnumNextNetShare;
  477. netSharesTypeData.AbortEnumPhysicalObject = AbortEnumNetShare;
  478. netSharesTypeData.ConvertObjectToMultiSz = ConvertNetShareToMultiSz;
  479. netSharesTypeData.ConvertMultiSzToObject = ConvertMultiSzToNetShare;
  480. netSharesTypeData.GetNativeObjectName = GetNativeNetShareName;
  481. netSharesTypeData.AcquirePhysicalObject = AcquireNetShare;
  482. netSharesTypeData.ReleasePhysicalObject = ReleaseNetShare;
  483. netSharesTypeData.ConvertObjectContentToUnicode = ConvertNetShareContentToUnicode;
  484. netSharesTypeData.ConvertObjectContentToAnsi = ConvertNetShareContentToAnsi;
  485. netSharesTypeData.FreeConvertedObjectContent = FreeConvertedNetShareContent;
  486. g_NetShareTypeId = IsmRegisterObjectType (
  487. S_NETSHARES_NAME,
  488. TRUE,
  489. FALSE,
  490. &netSharesTypeData
  491. );
  492. } else {
  493. netSharesTypeData.EnumFirstPhysicalObject = EnumFirstNetShare;
  494. netSharesTypeData.EnumNextPhysicalObject = EnumNextNetShare;
  495. netSharesTypeData.AbortEnumPhysicalObject = AbortEnumNetShare;
  496. netSharesTypeData.ConvertObjectToMultiSz = ConvertNetShareToMultiSz;
  497. netSharesTypeData.ConvertMultiSzToObject = ConvertMultiSzToNetShare;
  498. netSharesTypeData.GetNativeObjectName = GetNativeNetShareName;
  499. netSharesTypeData.AcquirePhysicalObject = AcquireNetShare;
  500. netSharesTypeData.ReleasePhysicalObject = ReleaseNetShare;
  501. netSharesTypeData.DoesPhysicalObjectExist = DoesNetShareExist;
  502. netSharesTypeData.RemovePhysicalObject = RemoveNetShare;
  503. netSharesTypeData.CreatePhysicalObject = CreateNetShare;
  504. netSharesTypeData.ConvertObjectContentToUnicode = ConvertNetShareContentToUnicode;
  505. netSharesTypeData.ConvertObjectContentToAnsi = ConvertNetShareContentToAnsi;
  506. netSharesTypeData.FreeConvertedObjectContent = FreeConvertedNetShareContent;
  507. g_NetShareTypeId = IsmRegisterObjectType (
  508. S_NETSHARES_NAME,
  509. TRUE,
  510. FALSE,
  511. &netSharesTypeData
  512. );
  513. pLoadNetEntries ();
  514. }
  515. MYASSERT (g_NetShareTypeId);
  516. return TRUE;
  517. }
  518. UINT
  519. NetSharesCallback (
  520. IN PCMIG_OBJECTENUMDATA Data,
  521. IN ULONG_PTR CallerArg
  522. )
  523. {
  524. //
  525. // This callback gets called for each net share. We simply mark the
  526. // share to be applied.
  527. //
  528. IsmMakeApplyObject (Data->ObjectTypeId, Data->ObjectName);
  529. return CALLBACK_ENUM_CONTINUE;
  530. }
  531. BOOL
  532. WINAPI
  533. NetSharesSgmInitialize (
  534. IN PMIG_LOGCALLBACK LogCallback,
  535. IN PVOID Reserved
  536. )
  537. {
  538. //
  539. // Set the log callback (so all log messages to to the app)
  540. //
  541. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  542. return TRUE;
  543. }
  544. BOOL
  545. WINAPI
  546. NetSharesSgmParse (
  547. IN PVOID Reserved
  548. )
  549. {
  550. PCTSTR friendlyName;
  551. friendlyName = GetStringResource (MSG_NET_SHARE_NAME);
  552. IsmAddComponentAlias (
  553. S_NETSHARES_NAME,
  554. MASTERGROUP_SYSTEM,
  555. friendlyName,
  556. COMPONENT_NAME,
  557. FALSE
  558. );
  559. FreeStringResource (friendlyName);
  560. return TRUE;
  561. }
  562. BOOL
  563. WINAPI
  564. NetSharesSgmQueueEnumeration (
  565. IN PVOID Reserved
  566. )
  567. {
  568. ENCODEDSTRHANDLE pattern;
  569. if (!IsmIsComponentSelected (S_NETSHARES_NAME, 0)) {
  570. g_NetSharesMigEnabled = FALSE;
  571. return TRUE;
  572. }
  573. g_NetSharesMigEnabled = TRUE;
  574. //
  575. // Queue all net shares to be applied. This could be enhanced to allow a
  576. // script to drive what should be restored.
  577. //
  578. pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, FALSE);
  579. IsmQueueEnumeration (g_NetShareTypeId, pattern, NetSharesCallback, (ULONG_PTR) 0, S_NETSHARES_NAME);
  580. IsmDestroyObjectHandle (pattern);
  581. return TRUE;
  582. }
  583. BOOL
  584. NetSharesVcmInitialize (
  585. IN PMIG_LOGCALLBACK LogCallback,
  586. IN PVOID Reserved
  587. )
  588. {
  589. //
  590. // Set the log callback (so all log messages to to the app)
  591. //
  592. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  593. return TRUE;
  594. }
  595. BOOL
  596. WINAPI
  597. NetSharesVcmParse (
  598. IN PVOID Reserved
  599. )
  600. {
  601. return NetSharesSgmParse (Reserved);
  602. }
  603. BOOL
  604. WINAPI
  605. NetSharesVcmQueueEnumeration (
  606. IN PVOID Reserved
  607. )
  608. {
  609. ENCODEDSTRHANDLE pattern;
  610. if (!IsmIsComponentSelected (S_NETSHARES_NAME, 0)) {
  611. g_NetSharesMigEnabled = FALSE;
  612. return TRUE;
  613. }
  614. g_NetSharesMigEnabled = TRUE;
  615. //
  616. // Queue all net share objects to be marked as persistent
  617. //
  618. pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, FALSE);
  619. IsmQueueEnumeration (g_NetShareTypeId, pattern, NetSharesCallback, (ULONG_PTR) 0, S_NETSHARES_NAME);
  620. IsmDestroyObjectHandle (pattern);
  621. return TRUE;
  622. }
  623. BOOL
  624. pEnumNetShareWorker (
  625. OUT PMIG_TYPEOBJECTENUM EnumPtr,
  626. IN PNETSHARE_ENUM NetShareEnum
  627. )
  628. {
  629. //
  630. // Test enumerated item against the pattern, and return only
  631. // when the pattern matches. Also, fill the entire enum
  632. // structure upon successful enumeration.
  633. //
  634. IsmDestroyObjectString (EnumPtr->ObjectNode);
  635. EnumPtr->ObjectNode = NULL;
  636. IsmDestroyObjectString (EnumPtr->ObjectLeaf);
  637. EnumPtr->ObjectLeaf = NULL;
  638. for (;;) {
  639. EnumPtr->ObjectName = IsmCreateObjectHandle (NetShareEnum->HashData.String, NULL);
  640. if (!ObsPatternMatch (NetShareEnum->Pattern, EnumPtr->ObjectName)) {
  641. if (!EnumNextHashTableString (&NetShareEnum->HashData)) {
  642. AbortEnumNetShare (EnumPtr);
  643. return FALSE;
  644. }
  645. continue;
  646. }
  647. EnumPtr->NativeObjectName = NetShareEnum->HashData.String;
  648. IsmCreateObjectStringsFromHandle (EnumPtr->ObjectName, &EnumPtr->ObjectNode, &EnumPtr->ObjectLeaf);
  649. EnumPtr->Level = 1;
  650. EnumPtr->SubLevel = 0;
  651. EnumPtr->IsLeaf = FALSE;
  652. EnumPtr->IsNode = TRUE;
  653. EnumPtr->Details.DetailsSize = 0;
  654. EnumPtr->Details.DetailsData = NULL;
  655. break;
  656. }
  657. return TRUE;
  658. }
  659. BOOL
  660. EnumFirstNetShare (
  661. IN OUT PMIG_TYPEOBJECTENUM EnumPtr, CALLER_INITIALIZED
  662. IN MIG_OBJECTSTRINGHANDLE Pattern,
  663. IN UINT MaxLevel
  664. )
  665. {
  666. PNETSHARE_ENUM netShareEnum = NULL;
  667. if (!g_NetSharesTable) {
  668. return FALSE;
  669. }
  670. netShareEnum = (PNETSHARE_ENUM) PmGetMemory (g_NetSharesPool, sizeof (NETSHARE_ENUM));
  671. netShareEnum->Pattern = PmDuplicateString (g_NetSharesPool, Pattern);
  672. EnumPtr->EtmHandle = (LONG_PTR) netShareEnum;
  673. if (EnumFirstHashTableString (&netShareEnum->HashData, g_NetSharesTable)) {
  674. return pEnumNetShareWorker (EnumPtr, netShareEnum);
  675. }
  676. AbortEnumNetShare (EnumPtr);
  677. return FALSE;
  678. }
  679. BOOL
  680. EnumNextNetShare (
  681. IN OUT PMIG_TYPEOBJECTENUM EnumPtr
  682. )
  683. {
  684. PNETSHARE_ENUM netShareEnum = NULL;
  685. netShareEnum = (PNETSHARE_ENUM)(EnumPtr->EtmHandle);
  686. if (!netShareEnum) {
  687. return FALSE;
  688. }
  689. if (EnumPtr->ObjectName) {
  690. IsmDestroyObjectHandle (EnumPtr->ObjectName);
  691. EnumPtr->ObjectName = NULL;
  692. }
  693. if (EnumNextHashTableString (&netShareEnum->HashData)) {
  694. return pEnumNetShareWorker (EnumPtr, netShareEnum);
  695. }
  696. AbortEnumNetShare (EnumPtr);
  697. return FALSE;
  698. }
  699. VOID
  700. AbortEnumNetShare (
  701. IN OUT PMIG_TYPEOBJECTENUM EnumPtr
  702. )
  703. {
  704. PNETSHARE_ENUM netShareEnum = NULL;
  705. MYASSERT (EnumPtr);
  706. netShareEnum = (PNETSHARE_ENUM)(EnumPtr->EtmHandle);
  707. if (!netShareEnum) {
  708. return;
  709. }
  710. IsmDestroyObjectHandle (EnumPtr->ObjectName);
  711. IsmDestroyObjectString (EnumPtr->ObjectNode);
  712. IsmDestroyObjectString (EnumPtr->ObjectLeaf);
  713. PmReleaseMemory (g_NetSharesPool, netShareEnum->Pattern);
  714. PmReleaseMemory (g_NetSharesPool, netShareEnum);
  715. ZeroMemory (EnumPtr, sizeof (MIG_TYPEOBJECTENUM));
  716. }
  717. BOOL
  718. AcquireNetShare (
  719. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  720. IN OUT PMIG_CONTENT ObjectContent,
  721. IN MIG_CONTENTTYPE ContentType,
  722. IN UINT MemoryContentLimit
  723. )
  724. {
  725. PCTSTR node;
  726. PCTSTR leaf;
  727. PNETSHARE_DATA netshareData;
  728. BOOL result = FALSE;
  729. if (!ObjectContent) {
  730. return FALSE;
  731. }
  732. //
  733. // NOTE: Do not zero ObjectContent; some of its members were already set
  734. //
  735. if (ContentType == CONTENTTYPE_FILE) {
  736. // nobody should request this as a file
  737. DEBUGMSG ((
  738. DBG_WHOOPS,
  739. "Unexpected acquire request for %s: Can't acquire net shares as files",
  740. ObjectName
  741. ));
  742. return FALSE;
  743. }
  744. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  745. if (HtFindStringEx (g_NetSharesTable, node, (PVOID)&netshareData, FALSE)) {
  746. //
  747. // Fill in all the content members. We already zeroed the struct,
  748. // so most of the members are taken care of because they are zero.
  749. //
  750. ObjectContent->MemoryContent.ContentBytes = (PBYTE)netshareData;
  751. ObjectContent->MemoryContent.ContentSize = sizeof(NETSHARE_DATA);
  752. result = TRUE;
  753. }
  754. IsmDestroyObjectString (node);
  755. INVALID_POINTER (node);
  756. IsmDestroyObjectString (leaf);
  757. INVALID_POINTER (leaf);
  758. }
  759. return result;
  760. }
  761. BOOL
  762. ReleaseNetShare (
  763. IN OUT PMIG_CONTENT ObjectContent
  764. )
  765. {
  766. //
  767. // Clean up routine for the AcquireNetShare function
  768. //
  769. if (ObjectContent) {
  770. ZeroMemory (ObjectContent, sizeof (MIG_CONTENT));
  771. }
  772. return TRUE;
  773. }
  774. BOOL
  775. DoesNetShareExist (
  776. IN MIG_OBJECTSTRINGHANDLE ObjectName
  777. )
  778. {
  779. PCTSTR node;
  780. PCTSTR leaf;
  781. BOOL result = FALSE;
  782. //
  783. // Given an object name (the net share), we must test to see if the
  784. // share exists on the machine. A table was built at initialization
  785. // time to provide fast access to net shares.
  786. //
  787. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  788. if (HtFindStringEx (g_NetSharesTable, node, NULL, FALSE)) {
  789. result = TRUE;
  790. }
  791. IsmDestroyObjectString (node);
  792. INVALID_POINTER (node);
  793. IsmDestroyObjectString (leaf);
  794. INVALID_POINTER (leaf);
  795. }
  796. return result;
  797. }
  798. BOOL
  799. RemoveNetShare (
  800. IN MIG_OBJECTSTRINGHANDLE ObjectName
  801. )
  802. {
  803. PCTSTR node;
  804. PCTSTR leaf;
  805. DWORD result = ERROR_NOT_FOUND;
  806. PCWSTR name;
  807. //
  808. // Given an object name (the net share), we must delete the share.
  809. //
  810. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  811. if (node && (!leaf)) {
  812. if (g_IsWin9x) {
  813. // JTJT: add here
  814. } else {
  815. name = CreateUnicode (node);
  816. if (g_NetShareDelW) {
  817. // record value name deletion
  818. IsmRecordOperation (JRNOP_DELETE,
  819. g_NetShareTypeId,
  820. ObjectName);
  821. result = g_NetShareDelW (NULL, (PWSTR) name, 0);
  822. } else {
  823. result = ERROR_CALL_NOT_IMPLEMENTED;
  824. }
  825. DestroyUnicode (name);
  826. }
  827. if (result != NERR_Success) {
  828. DEBUGMSG ((DBG_NETSHARES, "Failed to delete existent net share %s", name));
  829. } else {
  830. HtRemoveString (g_NetSharesTable, node);
  831. }
  832. }
  833. IsmDestroyObjectString (node);
  834. INVALID_POINTER (node);
  835. IsmDestroyObjectString (leaf);
  836. INVALID_POINTER (leaf);
  837. }
  838. return (result == NERR_Success);
  839. }
  840. BOOL
  841. CreateNetShare (
  842. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  843. IN PMIG_CONTENT ObjectContent
  844. )
  845. {
  846. PCTSTR node;
  847. PCTSTR leaf;
  848. DWORD result = NERR_Success;
  849. DWORD level;
  850. SHARE_INFO_502 shareInfo;
  851. PNETSHARE_DATA netshareData = NULL;
  852. //
  853. // The name of the net share is in the object name's node. The net share
  854. // content provides the path of the share. Details provide the net share
  855. // ACLs.
  856. //
  857. // Our job is to take the object name, content and details, and create a
  858. // share. We ignore the case where the content is in a file. This should
  859. // not apply to net shares.
  860. //
  861. if (!ObjectContent->ContentInFile) {
  862. if (ObjectContent->MemoryContent.ContentBytes && ObjectContent->MemoryContent.ContentSize) {
  863. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  864. if (node && (!leaf)) {
  865. level = (g_IsWin9x ? 50 : 502);
  866. netshareData = (PNETSHARE_DATA) PmGetMemory (g_NetSharesPool, sizeof (NETSHARE_DATA));
  867. CopyMemory (netshareData,
  868. ObjectContent->MemoryContent.ContentBytes,
  869. sizeof(NETSHARE_DATA));
  870. if (DoesFileExist (netshareData->sharePath)) {
  871. if (g_IsWin9x) {
  872. // JTJT: add here
  873. } else {
  874. shareInfo.shi502_netname = (PWSTR) CreateUnicode (node);
  875. shareInfo.shi502_path = (PWSTR) CreateUnicode (netshareData->sharePath);
  876. shareInfo.shi502_type = STYPE_DISKTREE; // JTJTJT: retrieve type
  877. shareInfo.shi502_remark = NULL; // JTJTJT: retrieve remark
  878. shareInfo.shi502_permissions = ACCESS_ALL; // JTJTJT: retrieve perms
  879. shareInfo.shi502_max_uses = -1; // JTJTJT: retrieve max uses
  880. shareInfo.shi502_current_uses = 0;
  881. shareInfo.shi502_passwd = NULL; // JTJTJT: retrieve password
  882. shareInfo.shi502_reserved = 0;
  883. shareInfo.shi502_security_descriptor = NULL; // JTJTJT: retrieve ACLs
  884. if (g_NetShareAddW) {
  885. IsmRecordOperation (JRNOP_CREATE,
  886. g_NetShareTypeId,
  887. ObjectName);
  888. result = g_NetShareAddW (NULL, level, (PBYTE)&shareInfo, NULL);
  889. } else {
  890. result = ERROR_CALL_NOT_IMPLEMENTED;
  891. }
  892. DestroyUnicode (shareInfo.shi502_netname);
  893. DestroyUnicode (shareInfo.shi502_path);
  894. }
  895. if (result != NERR_Success) {
  896. DEBUGMSG ((DBG_NETSHARES, "Failed to add net share for %s", node));
  897. } else {
  898. HtAddStringEx (g_NetSharesTable, node, &netshareData, FALSE);
  899. }
  900. }
  901. PmReleaseMemory (g_NetSharesPool, netshareData);
  902. }
  903. IsmDestroyObjectString (node);
  904. INVALID_POINTER (node);
  905. IsmDestroyObjectString (leaf);
  906. INVALID_POINTER (leaf);
  907. }
  908. }
  909. } else {
  910. DEBUGMSG ((DBG_WHOOPS, "Did not expect content to come in the form of a file."));
  911. }
  912. return (result == NERR_Success);
  913. }
  914. PCTSTR
  915. ConvertNetShareToMultiSz (
  916. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  917. IN PMIG_CONTENT ObjectContent
  918. )
  919. {
  920. PCTSTR node = NULL, leaf = NULL;
  921. PTSTR result;
  922. PNETSHARE_DATA netshareData;
  923. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  924. //
  925. // Copy field 1 (share name) and field 2 (share path) to a temp
  926. // multi-sz buffer
  927. //
  928. MYASSERT (!ObjectContent->ContentInFile);
  929. MYASSERT (ObjectContent->MemoryContent.ContentBytes);
  930. g_NetShareConversionBuff.End = 0;
  931. GbCopyQuotedString (&g_NetShareConversionBuff, node);
  932. if (ObjectContent->MemoryContent.ContentBytes) {
  933. netshareData = (PNETSHARE_DATA) PmGetMemory (g_NetSharesPool, sizeof (NETSHARE_DATA));
  934. CopyMemory (&netshareData->sharePath, ObjectContent->MemoryContent.ContentBytes, sizeof(NETSHARE_DATA));
  935. GbCopyQuotedString (&g_NetShareConversionBuff, netshareData->sharePath);
  936. PmReleaseMemory (g_NetSharesPool, netshareData);
  937. netshareData = NULL;
  938. }
  939. IsmDestroyObjectString (node);
  940. INVALID_POINTER (node);
  941. IsmDestroyObjectString (leaf);
  942. INVALID_POINTER (leaf);
  943. }
  944. //
  945. // Terminate the multi-sz
  946. //
  947. GbCopyString (&g_NetShareConversionBuff, TEXT(""));
  948. //
  949. // Transfer temp buffer to an ISM-allocated buffer and forget about it
  950. //
  951. result = IsmGetMemory (g_NetShareConversionBuff.End);
  952. CopyMemory (result, g_NetShareConversionBuff.Buf, g_NetShareConversionBuff.End);
  953. return result;
  954. }
  955. BOOL
  956. ConvertMultiSzToNetShare (
  957. IN PCTSTR ObjectMultiSz,
  958. OUT MIG_OBJECTSTRINGHANDLE *ObjectName,
  959. OUT PMIG_CONTENT ObjectContent OPTIONAL
  960. )
  961. {
  962. MULTISZ_ENUM e;
  963. PCTSTR localName = NULL;
  964. UINT index;
  965. NETSHARE_DATA netshareData;
  966. BOOL pathFound = FALSE;
  967. //
  968. // Parse the multi-sz into the net share content and details.
  969. // The user may have edited the text (and potentially introduced
  970. // errors).
  971. //
  972. ZeroMemory (&netshareData, sizeof (NETSHARE_DATA));
  973. if (ObjectContent) {
  974. ZeroMemory (ObjectContent, sizeof (MIG_CONTENT));
  975. }
  976. if (EnumFirstMultiSz (&e, ObjectMultiSz)) {
  977. index = 0;
  978. do {
  979. switch (index) {
  980. case INDEXLOCAL:
  981. localName = e.CurrentString;
  982. break;
  983. case INDEXREMOTE:
  984. pathFound = TRUE;
  985. StringCopy (netshareData.sharePath, e.CurrentString);
  986. break;
  987. default:
  988. // Ignore extra data
  989. DEBUGMSG ((DBG_WARNING, "Extra net share string ignored: %s", e.CurrentString));
  990. break;
  991. }
  992. index++;
  993. } while (EnumNextMultiSz (&e));
  994. }
  995. if (!localName || !pathFound) {
  996. //
  997. // Bogus data, fail
  998. //
  999. return FALSE;
  1000. }
  1001. //
  1002. // Fill in all the members of the content structure. Keep in mind
  1003. // we already zeroed the buffer.
  1004. //
  1005. *ObjectName = IsmCreateObjectHandle (localName, NULL);
  1006. if (ObjectContent) {
  1007. ObjectContent->MemoryContent.ContentBytes = IsmGetMemory (sizeof (NETSHARE_DATA));
  1008. CopyMemory ((PBYTE) ObjectContent->MemoryContent.ContentBytes, &netshareData, sizeof (NETSHARE_DATA));
  1009. ObjectContent->MemoryContent.ContentSize = sizeof (NETSHARE_DATA);
  1010. }
  1011. return TRUE;
  1012. }
  1013. PCTSTR
  1014. GetNativeNetShareName (
  1015. IN MIG_OBJECTSTRINGHANDLE ObjectName
  1016. )
  1017. {
  1018. PCTSTR node, leaf;
  1019. UINT size;
  1020. PTSTR result = NULL;
  1021. //
  1022. // The "native" format is what most people would use to describe our
  1023. // object. For the net share case, we simply get the share name from the
  1024. // node; the node is not encoded in any way, and the leaf is not used.
  1025. //
  1026. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  1027. if (node) {
  1028. size = SizeOfString (node);
  1029. if (size) {
  1030. result = IsmGetMemory (size);
  1031. CopyMemory (result, node, size);
  1032. }
  1033. }
  1034. IsmDestroyObjectString (node);
  1035. INVALID_POINTER (node);
  1036. IsmDestroyObjectString (leaf);
  1037. INVALID_POINTER (leaf);
  1038. }
  1039. return result;
  1040. }
  1041. PMIG_CONTENT
  1042. ConvertNetShareContentToUnicode (
  1043. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1044. IN PMIG_CONTENT ObjectContent
  1045. )
  1046. {
  1047. PMIG_CONTENT result = NULL;
  1048. if (!ObjectContent) {
  1049. return result;
  1050. }
  1051. if (ObjectContent->ContentInFile) {
  1052. return result;
  1053. }
  1054. result = IsmGetMemory (sizeof (MIG_CONTENT));
  1055. if (result) {
  1056. CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
  1057. if ((ObjectContent->MemoryContent.ContentSize != 0) &&
  1058. (ObjectContent->MemoryContent.ContentBytes != NULL)
  1059. ) {
  1060. // convert Mapped Drive content
  1061. result->MemoryContent.ContentBytes = IsmGetMemory (sizeof (NETSHARE_DATAW));
  1062. if (result->MemoryContent.ContentBytes) {
  1063. DirectDbcsToUnicodeN (
  1064. ((PNETSHARE_DATAW)result->MemoryContent.ContentBytes)->sharePath,
  1065. ((PNETSHARE_DATAA)ObjectContent->MemoryContent.ContentBytes)->sharePath,
  1066. MAX_PATH + 1
  1067. );
  1068. result->MemoryContent.ContentSize = sizeof (NETSHARE_DATAW);
  1069. }
  1070. }
  1071. }
  1072. return result;
  1073. }
  1074. PMIG_CONTENT
  1075. ConvertNetShareContentToAnsi (
  1076. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1077. IN PMIG_CONTENT ObjectContent
  1078. )
  1079. {
  1080. PMIG_CONTENT result = NULL;
  1081. if (!ObjectContent) {
  1082. return result;
  1083. }
  1084. if (ObjectContent->ContentInFile) {
  1085. return result;
  1086. }
  1087. result = IsmGetMemory (sizeof (MIG_CONTENT));
  1088. if (result) {
  1089. CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
  1090. if ((ObjectContent->MemoryContent.ContentSize != 0) &&
  1091. (ObjectContent->MemoryContent.ContentBytes != NULL)
  1092. ) {
  1093. // convert Mapped Drive content
  1094. result->MemoryContent.ContentBytes = IsmGetMemory (sizeof (NETSHARE_DATAA));
  1095. if (result->MemoryContent.ContentBytes) {
  1096. DirectUnicodeToDbcsN (
  1097. ((PNETSHARE_DATAA)result->MemoryContent.ContentBytes)->sharePath,
  1098. ((PNETSHARE_DATAW)ObjectContent->MemoryContent.ContentBytes)->sharePath,
  1099. MAX_PATH + 1
  1100. );
  1101. result->MemoryContent.ContentSize = sizeof (NETSHARE_DATAA);
  1102. }
  1103. }
  1104. }
  1105. return result;
  1106. }
  1107. BOOL
  1108. FreeConvertedNetShareContent (
  1109. IN PMIG_CONTENT ObjectContent
  1110. )
  1111. {
  1112. if (!ObjectContent) {
  1113. return TRUE;
  1114. }
  1115. if (ObjectContent->MemoryContent.ContentBytes) {
  1116. IsmReleaseMemory (ObjectContent->MemoryContent.ContentBytes);
  1117. }
  1118. IsmReleaseMemory (ObjectContent);
  1119. return TRUE;
  1120. }