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.

1377 lines
40 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. StringCopyTcharCount (netshareData->sharePath, path, MAX_PATH + 1);
  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. StringCopyTcharCount (netshareData->sharePath, path, MAX_PATH + 1);
  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. netSharesTypeData.Priority = PRIORITY_NETSHARE;
  475. if (Platform == PLATFORM_SOURCE) {
  476. netSharesTypeData.EnumFirstPhysicalObject = EnumFirstNetShare;
  477. netSharesTypeData.EnumNextPhysicalObject = EnumNextNetShare;
  478. netSharesTypeData.AbortEnumPhysicalObject = AbortEnumNetShare;
  479. netSharesTypeData.ConvertObjectToMultiSz = ConvertNetShareToMultiSz;
  480. netSharesTypeData.ConvertMultiSzToObject = ConvertMultiSzToNetShare;
  481. netSharesTypeData.GetNativeObjectName = GetNativeNetShareName;
  482. netSharesTypeData.AcquirePhysicalObject = AcquireNetShare;
  483. netSharesTypeData.ReleasePhysicalObject = ReleaseNetShare;
  484. netSharesTypeData.ConvertObjectContentToUnicode = ConvertNetShareContentToUnicode;
  485. netSharesTypeData.ConvertObjectContentToAnsi = ConvertNetShareContentToAnsi;
  486. netSharesTypeData.FreeConvertedObjectContent = FreeConvertedNetShareContent;
  487. g_NetShareTypeId = IsmRegisterObjectType (
  488. S_NETSHARES_NAME,
  489. TRUE,
  490. FALSE,
  491. &netSharesTypeData
  492. );
  493. } else {
  494. netSharesTypeData.EnumFirstPhysicalObject = EnumFirstNetShare;
  495. netSharesTypeData.EnumNextPhysicalObject = EnumNextNetShare;
  496. netSharesTypeData.AbortEnumPhysicalObject = AbortEnumNetShare;
  497. netSharesTypeData.ConvertObjectToMultiSz = ConvertNetShareToMultiSz;
  498. netSharesTypeData.ConvertMultiSzToObject = ConvertMultiSzToNetShare;
  499. netSharesTypeData.GetNativeObjectName = GetNativeNetShareName;
  500. netSharesTypeData.AcquirePhysicalObject = AcquireNetShare;
  501. netSharesTypeData.ReleasePhysicalObject = ReleaseNetShare;
  502. netSharesTypeData.DoesPhysicalObjectExist = DoesNetShareExist;
  503. netSharesTypeData.RemovePhysicalObject = RemoveNetShare;
  504. netSharesTypeData.CreatePhysicalObject = CreateNetShare;
  505. netSharesTypeData.ConvertObjectContentToUnicode = ConvertNetShareContentToUnicode;
  506. netSharesTypeData.ConvertObjectContentToAnsi = ConvertNetShareContentToAnsi;
  507. netSharesTypeData.FreeConvertedObjectContent = FreeConvertedNetShareContent;
  508. g_NetShareTypeId = IsmRegisterObjectType (
  509. S_NETSHARES_NAME,
  510. TRUE,
  511. FALSE,
  512. &netSharesTypeData
  513. );
  514. pLoadNetEntries ();
  515. }
  516. MYASSERT (g_NetShareTypeId);
  517. return TRUE;
  518. }
  519. UINT
  520. NetSharesCallback (
  521. IN PCMIG_OBJECTENUMDATA Data,
  522. IN ULONG_PTR CallerArg
  523. )
  524. {
  525. //
  526. // This callback gets called for each net share. We simply mark the
  527. // share to be applied.
  528. //
  529. IsmMakeApplyObject (Data->ObjectTypeId, Data->ObjectName);
  530. return CALLBACK_ENUM_CONTINUE;
  531. }
  532. BOOL
  533. WINAPI
  534. NetSharesSgmInitialize (
  535. IN PMIG_LOGCALLBACK LogCallback,
  536. IN PVOID Reserved
  537. )
  538. {
  539. //
  540. // Set the log callback (so all log messages to to the app)
  541. //
  542. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  543. return TRUE;
  544. }
  545. BOOL
  546. WINAPI
  547. NetSharesSgmParse (
  548. IN PVOID Reserved
  549. )
  550. {
  551. PCTSTR friendlyName;
  552. friendlyName = GetStringResource (MSG_NET_SHARE_NAME);
  553. IsmAddComponentAlias (
  554. S_NETSHARES_NAME,
  555. MASTERGROUP_SYSTEM,
  556. friendlyName,
  557. COMPONENT_NAME,
  558. FALSE
  559. );
  560. FreeStringResource (friendlyName);
  561. return TRUE;
  562. }
  563. BOOL
  564. WINAPI
  565. NetSharesSgmQueueEnumeration (
  566. IN PVOID Reserved
  567. )
  568. {
  569. ENCODEDSTRHANDLE pattern;
  570. if (!IsmIsComponentSelected (S_NETSHARES_NAME, 0)) {
  571. g_NetSharesMigEnabled = FALSE;
  572. return TRUE;
  573. }
  574. g_NetSharesMigEnabled = TRUE;
  575. //
  576. // Queue all net shares to be applied. This could be enhanced to allow a
  577. // script to drive what should be restored.
  578. //
  579. pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, FALSE);
  580. IsmQueueEnumeration (g_NetShareTypeId, pattern, NetSharesCallback, (ULONG_PTR) 0, S_NETSHARES_NAME);
  581. IsmDestroyObjectHandle (pattern);
  582. return TRUE;
  583. }
  584. BOOL
  585. NetSharesVcmInitialize (
  586. IN PMIG_LOGCALLBACK LogCallback,
  587. IN PVOID Reserved
  588. )
  589. {
  590. //
  591. // Set the log callback (so all log messages to to the app)
  592. //
  593. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  594. return TRUE;
  595. }
  596. BOOL
  597. WINAPI
  598. NetSharesVcmParse (
  599. IN PVOID Reserved
  600. )
  601. {
  602. return NetSharesSgmParse (Reserved);
  603. }
  604. BOOL
  605. WINAPI
  606. NetSharesVcmQueueEnumeration (
  607. IN PVOID Reserved
  608. )
  609. {
  610. ENCODEDSTRHANDLE pattern;
  611. if (!IsmIsComponentSelected (S_NETSHARES_NAME, 0)) {
  612. g_NetSharesMigEnabled = FALSE;
  613. return TRUE;
  614. }
  615. g_NetSharesMigEnabled = TRUE;
  616. //
  617. // Queue all net share objects to be marked as persistent
  618. //
  619. pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, FALSE);
  620. IsmQueueEnumeration (g_NetShareTypeId, pattern, NetSharesCallback, (ULONG_PTR) 0, S_NETSHARES_NAME);
  621. IsmDestroyObjectHandle (pattern);
  622. return TRUE;
  623. }
  624. BOOL
  625. pEnumNetShareWorker (
  626. OUT PMIG_TYPEOBJECTENUM EnumPtr,
  627. IN PNETSHARE_ENUM NetShareEnum
  628. )
  629. {
  630. //
  631. // Test enumerated item against the pattern, and return only
  632. // when the pattern matches. Also, fill the entire enum
  633. // structure upon successful enumeration.
  634. //
  635. IsmDestroyObjectString (EnumPtr->ObjectNode);
  636. EnumPtr->ObjectNode = NULL;
  637. IsmDestroyObjectString (EnumPtr->ObjectLeaf);
  638. EnumPtr->ObjectLeaf = NULL;
  639. for (;;) {
  640. EnumPtr->ObjectName = IsmCreateObjectHandle (NetShareEnum->HashData.String, NULL);
  641. if (!ObsPatternMatch (NetShareEnum->Pattern, EnumPtr->ObjectName)) {
  642. if (!EnumNextHashTableString (&NetShareEnum->HashData)) {
  643. AbortEnumNetShare (EnumPtr);
  644. return FALSE;
  645. }
  646. continue;
  647. }
  648. EnumPtr->NativeObjectName = NetShareEnum->HashData.String;
  649. IsmCreateObjectStringsFromHandle (EnumPtr->ObjectName, &EnumPtr->ObjectNode, &EnumPtr->ObjectLeaf);
  650. EnumPtr->Level = 1;
  651. EnumPtr->SubLevel = 0;
  652. EnumPtr->IsLeaf = FALSE;
  653. EnumPtr->IsNode = TRUE;
  654. EnumPtr->Details.DetailsSize = 0;
  655. EnumPtr->Details.DetailsData = NULL;
  656. break;
  657. }
  658. return TRUE;
  659. }
  660. BOOL
  661. EnumFirstNetShare (
  662. IN OUT PMIG_TYPEOBJECTENUM EnumPtr, CALLER_INITIALIZED
  663. IN MIG_OBJECTSTRINGHANDLE Pattern,
  664. IN UINT MaxLevel
  665. )
  666. {
  667. PNETSHARE_ENUM netShareEnum = NULL;
  668. if (!g_NetSharesTable) {
  669. return FALSE;
  670. }
  671. netShareEnum = (PNETSHARE_ENUM) PmGetMemory (g_NetSharesPool, sizeof (NETSHARE_ENUM));
  672. netShareEnum->Pattern = PmDuplicateString (g_NetSharesPool, Pattern);
  673. EnumPtr->EtmHandle = (LONG_PTR) netShareEnum;
  674. if (EnumFirstHashTableString (&netShareEnum->HashData, g_NetSharesTable)) {
  675. return pEnumNetShareWorker (EnumPtr, netShareEnum);
  676. }
  677. AbortEnumNetShare (EnumPtr);
  678. return FALSE;
  679. }
  680. BOOL
  681. EnumNextNetShare (
  682. IN OUT PMIG_TYPEOBJECTENUM EnumPtr
  683. )
  684. {
  685. PNETSHARE_ENUM netShareEnum = NULL;
  686. netShareEnum = (PNETSHARE_ENUM)(EnumPtr->EtmHandle);
  687. if (!netShareEnum) {
  688. return FALSE;
  689. }
  690. if (EnumPtr->ObjectName) {
  691. IsmDestroyObjectHandle (EnumPtr->ObjectName);
  692. EnumPtr->ObjectName = NULL;
  693. }
  694. if (EnumNextHashTableString (&netShareEnum->HashData)) {
  695. return pEnumNetShareWorker (EnumPtr, netShareEnum);
  696. }
  697. AbortEnumNetShare (EnumPtr);
  698. return FALSE;
  699. }
  700. VOID
  701. AbortEnumNetShare (
  702. IN OUT PMIG_TYPEOBJECTENUM EnumPtr
  703. )
  704. {
  705. PNETSHARE_ENUM netShareEnum = NULL;
  706. MYASSERT (EnumPtr);
  707. netShareEnum = (PNETSHARE_ENUM)(EnumPtr->EtmHandle);
  708. if (!netShareEnum) {
  709. return;
  710. }
  711. IsmDestroyObjectHandle (EnumPtr->ObjectName);
  712. IsmDestroyObjectString (EnumPtr->ObjectNode);
  713. IsmDestroyObjectString (EnumPtr->ObjectLeaf);
  714. PmReleaseMemory (g_NetSharesPool, netShareEnum->Pattern);
  715. PmReleaseMemory (g_NetSharesPool, netShareEnum);
  716. ZeroMemory (EnumPtr, sizeof (MIG_TYPEOBJECTENUM));
  717. }
  718. BOOL
  719. AcquireNetShare (
  720. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  721. IN OUT PMIG_CONTENT ObjectContent,
  722. IN MIG_CONTENTTYPE ContentType,
  723. IN UINT MemoryContentLimit
  724. )
  725. {
  726. PCTSTR node;
  727. PCTSTR leaf;
  728. PNETSHARE_DATA netshareData;
  729. BOOL result = FALSE;
  730. if (!ObjectContent) {
  731. return FALSE;
  732. }
  733. //
  734. // NOTE: Do not zero ObjectContent; some of its members were already set
  735. //
  736. if (ContentType == CONTENTTYPE_FILE) {
  737. // nobody should request this as a file
  738. DEBUGMSG ((
  739. DBG_WHOOPS,
  740. "Unexpected acquire request for %s: Can't acquire net shares as files",
  741. ObjectName
  742. ));
  743. return FALSE;
  744. }
  745. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  746. if (HtFindStringEx (g_NetSharesTable, node, (PVOID)&netshareData, FALSE)) {
  747. //
  748. // Fill in all the content members. We already zeroed the struct,
  749. // so most of the members are taken care of because they are zero.
  750. //
  751. ObjectContent->MemoryContent.ContentBytes = (PBYTE)netshareData;
  752. ObjectContent->MemoryContent.ContentSize = sizeof(NETSHARE_DATA);
  753. result = TRUE;
  754. }
  755. IsmDestroyObjectString (node);
  756. INVALID_POINTER (node);
  757. IsmDestroyObjectString (leaf);
  758. INVALID_POINTER (leaf);
  759. }
  760. return result;
  761. }
  762. BOOL
  763. ReleaseNetShare (
  764. IN OUT PMIG_CONTENT ObjectContent
  765. )
  766. {
  767. //
  768. // Clean up routine for the AcquireNetShare function
  769. //
  770. if (ObjectContent) {
  771. ZeroMemory (ObjectContent, sizeof (MIG_CONTENT));
  772. }
  773. return TRUE;
  774. }
  775. BOOL
  776. DoesNetShareExist (
  777. IN MIG_OBJECTSTRINGHANDLE ObjectName
  778. )
  779. {
  780. PCTSTR node;
  781. PCTSTR leaf;
  782. BOOL result = FALSE;
  783. //
  784. // Given an object name (the net share), we must test to see if the
  785. // share exists on the machine. A table was built at initialization
  786. // time to provide fast access to net shares.
  787. //
  788. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  789. if (HtFindStringEx (g_NetSharesTable, node, NULL, FALSE)) {
  790. result = TRUE;
  791. }
  792. IsmDestroyObjectString (node);
  793. INVALID_POINTER (node);
  794. IsmDestroyObjectString (leaf);
  795. INVALID_POINTER (leaf);
  796. }
  797. return result;
  798. }
  799. BOOL
  800. RemoveNetShare (
  801. IN MIG_OBJECTSTRINGHANDLE ObjectName
  802. )
  803. {
  804. PCTSTR node;
  805. PCTSTR leaf;
  806. DWORD result = ERROR_NOT_FOUND;
  807. PCWSTR name;
  808. //
  809. // Given an object name (the net share), we must delete the share.
  810. //
  811. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  812. if (node && (!leaf)) {
  813. if (g_IsWin9x) {
  814. // JTJT: add here
  815. } else {
  816. name = CreateUnicode (node);
  817. if (g_NetShareDelW) {
  818. // record value name deletion
  819. IsmRecordOperation (JRNOP_DELETE,
  820. g_NetShareTypeId,
  821. ObjectName);
  822. result = g_NetShareDelW (NULL, (PWSTR) name, 0);
  823. } else {
  824. result = ERROR_CALL_NOT_IMPLEMENTED;
  825. }
  826. DestroyUnicode (name);
  827. }
  828. if (result != NERR_Success) {
  829. DEBUGMSG ((DBG_NETSHARES, "Failed to delete existent net share %s", name));
  830. } else {
  831. HtRemoveString (g_NetSharesTable, node);
  832. }
  833. }
  834. IsmDestroyObjectString (node);
  835. INVALID_POINTER (node);
  836. IsmDestroyObjectString (leaf);
  837. INVALID_POINTER (leaf);
  838. }
  839. return (result == NERR_Success);
  840. }
  841. BOOL
  842. CreateNetShare (
  843. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  844. IN PMIG_CONTENT ObjectContent
  845. )
  846. {
  847. PCTSTR node;
  848. PCTSTR leaf;
  849. DWORD result = NERR_Success;
  850. DWORD level;
  851. SHARE_INFO_502 shareInfo;
  852. PNETSHARE_DATA netshareData = NULL;
  853. //
  854. // The name of the net share is in the object name's node. The net share
  855. // content provides the path of the share. Details provide the net share
  856. // ACLs.
  857. //
  858. // Our job is to take the object name, content and details, and create a
  859. // share. We ignore the case where the content is in a file. This should
  860. // not apply to net shares.
  861. //
  862. if (!ObjectContent->ContentInFile) {
  863. if (ObjectContent->MemoryContent.ContentBytes && ObjectContent->MemoryContent.ContentSize) {
  864. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  865. if (node && (!leaf)) {
  866. level = (g_IsWin9x ? 50 : 502);
  867. netshareData = (PNETSHARE_DATA) PmGetMemory (g_NetSharesPool, sizeof (NETSHARE_DATA));
  868. CopyMemory (netshareData,
  869. ObjectContent->MemoryContent.ContentBytes,
  870. sizeof(NETSHARE_DATA));
  871. if (DoesFileExist (netshareData->sharePath)) {
  872. if (g_IsWin9x) {
  873. // JTJT: add here
  874. } else {
  875. shareInfo.shi502_netname = (PWSTR) CreateUnicode (node);
  876. shareInfo.shi502_path = (PWSTR) CreateUnicode (netshareData->sharePath);
  877. shareInfo.shi502_type = STYPE_DISKTREE; // JTJTJT: retrieve type
  878. shareInfo.shi502_remark = NULL; // JTJTJT: retrieve remark
  879. shareInfo.shi502_permissions = ACCESS_ALL; // JTJTJT: retrieve perms
  880. shareInfo.shi502_max_uses = -1; // JTJTJT: retrieve max uses
  881. shareInfo.shi502_current_uses = 0;
  882. shareInfo.shi502_passwd = NULL; // JTJTJT: retrieve password
  883. shareInfo.shi502_reserved = 0;
  884. shareInfo.shi502_security_descriptor = NULL; // JTJTJT: retrieve ACLs
  885. if (g_NetShareAddW) {
  886. IsmRecordOperation (JRNOP_CREATE,
  887. g_NetShareTypeId,
  888. ObjectName);
  889. result = g_NetShareAddW (NULL, level, (PBYTE)&shareInfo, NULL);
  890. } else {
  891. result = ERROR_CALL_NOT_IMPLEMENTED;
  892. }
  893. DestroyUnicode (shareInfo.shi502_netname);
  894. DestroyUnicode (shareInfo.shi502_path);
  895. }
  896. if (result != NERR_Success) {
  897. DEBUGMSG ((DBG_NETSHARES, "Failed to add net share for %s", node));
  898. } else {
  899. HtAddStringEx (g_NetSharesTable, node, &netshareData, FALSE);
  900. }
  901. }
  902. PmReleaseMemory (g_NetSharesPool, netshareData);
  903. }
  904. IsmDestroyObjectString (node);
  905. INVALID_POINTER (node);
  906. IsmDestroyObjectString (leaf);
  907. INVALID_POINTER (leaf);
  908. }
  909. }
  910. } else {
  911. DEBUGMSG ((DBG_WHOOPS, "Did not expect content to come in the form of a file."));
  912. }
  913. return (result == NERR_Success);
  914. }
  915. PCTSTR
  916. ConvertNetShareToMultiSz (
  917. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  918. IN PMIG_CONTENT ObjectContent
  919. )
  920. {
  921. PCTSTR node = NULL, leaf = NULL;
  922. PTSTR result;
  923. PNETSHARE_DATA netshareData;
  924. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  925. //
  926. // Copy field 1 (share name) and field 2 (share path) to a temp
  927. // multi-sz buffer
  928. //
  929. MYASSERT (!ObjectContent->ContentInFile);
  930. MYASSERT (ObjectContent->MemoryContent.ContentBytes);
  931. g_NetShareConversionBuff.End = 0;
  932. GbCopyQuotedString (&g_NetShareConversionBuff, node);
  933. if (ObjectContent->MemoryContent.ContentBytes) {
  934. netshareData = (PNETSHARE_DATA) PmGetMemory (g_NetSharesPool, sizeof (NETSHARE_DATA));
  935. CopyMemory (&netshareData->sharePath, ObjectContent->MemoryContent.ContentBytes, sizeof(NETSHARE_DATA));
  936. GbCopyQuotedString (&g_NetShareConversionBuff, netshareData->sharePath);
  937. PmReleaseMemory (g_NetSharesPool, netshareData);
  938. netshareData = NULL;
  939. }
  940. IsmDestroyObjectString (node);
  941. INVALID_POINTER (node);
  942. IsmDestroyObjectString (leaf);
  943. INVALID_POINTER (leaf);
  944. }
  945. //
  946. // Terminate the multi-sz
  947. //
  948. GbCopyString (&g_NetShareConversionBuff, TEXT(""));
  949. //
  950. // Transfer temp buffer to an ISM-allocated buffer and forget about it
  951. //
  952. result = IsmGetMemory (g_NetShareConversionBuff.End);
  953. CopyMemory (result, g_NetShareConversionBuff.Buf, g_NetShareConversionBuff.End);
  954. return result;
  955. }
  956. BOOL
  957. ConvertMultiSzToNetShare (
  958. IN PCTSTR ObjectMultiSz,
  959. OUT MIG_OBJECTSTRINGHANDLE *ObjectName,
  960. OUT PMIG_CONTENT ObjectContent OPTIONAL
  961. )
  962. {
  963. MULTISZ_ENUM e;
  964. PCTSTR localName = NULL;
  965. UINT index;
  966. NETSHARE_DATA netshareData;
  967. BOOL pathFound = FALSE;
  968. //
  969. // Parse the multi-sz into the net share content and details.
  970. // The user may have edited the text (and potentially introduced
  971. // errors).
  972. //
  973. ZeroMemory (&netshareData, sizeof (NETSHARE_DATA));
  974. if (ObjectContent) {
  975. ZeroMemory (ObjectContent, sizeof (MIG_CONTENT));
  976. }
  977. if (EnumFirstMultiSz (&e, ObjectMultiSz)) {
  978. index = 0;
  979. do {
  980. switch (index) {
  981. case INDEXLOCAL:
  982. localName = e.CurrentString;
  983. break;
  984. case INDEXREMOTE:
  985. pathFound = TRUE;
  986. StringCopyTcharCount (netshareData.sharePath, e.CurrentString, MAX_PATH + 1);
  987. break;
  988. default:
  989. // Ignore extra data
  990. DEBUGMSG ((DBG_WARNING, "Extra net share string ignored: %s", e.CurrentString));
  991. break;
  992. }
  993. index++;
  994. } while (EnumNextMultiSz (&e));
  995. }
  996. if (!localName || !pathFound) {
  997. //
  998. // Bogus data, fail
  999. //
  1000. return FALSE;
  1001. }
  1002. //
  1003. // Fill in all the members of the content structure. Keep in mind
  1004. // we already zeroed the buffer.
  1005. //
  1006. *ObjectName = IsmCreateObjectHandle (localName, NULL);
  1007. if (ObjectContent) {
  1008. ObjectContent->MemoryContent.ContentBytes = IsmGetMemory (sizeof (NETSHARE_DATA));
  1009. CopyMemory ((PBYTE) ObjectContent->MemoryContent.ContentBytes, &netshareData, sizeof (NETSHARE_DATA));
  1010. ObjectContent->MemoryContent.ContentSize = sizeof (NETSHARE_DATA);
  1011. }
  1012. return TRUE;
  1013. }
  1014. PCTSTR
  1015. GetNativeNetShareName (
  1016. IN MIG_OBJECTSTRINGHANDLE ObjectName
  1017. )
  1018. {
  1019. PCTSTR node, leaf;
  1020. UINT size;
  1021. PTSTR result = NULL;
  1022. //
  1023. // The "native" format is what most people would use to describe our
  1024. // object. For the net share case, we simply get the share name from the
  1025. // node; the node is not encoded in any way, and the leaf is not used.
  1026. //
  1027. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  1028. if (node) {
  1029. size = SizeOfString (node);
  1030. if (size) {
  1031. result = IsmGetMemory (size);
  1032. CopyMemory (result, node, size);
  1033. }
  1034. }
  1035. IsmDestroyObjectString (node);
  1036. INVALID_POINTER (node);
  1037. IsmDestroyObjectString (leaf);
  1038. INVALID_POINTER (leaf);
  1039. }
  1040. return result;
  1041. }
  1042. PMIG_CONTENT
  1043. ConvertNetShareContentToUnicode (
  1044. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1045. IN PMIG_CONTENT ObjectContent
  1046. )
  1047. {
  1048. PMIG_CONTENT result = NULL;
  1049. if (!ObjectContent) {
  1050. return result;
  1051. }
  1052. if (ObjectContent->ContentInFile) {
  1053. return result;
  1054. }
  1055. result = IsmGetMemory (sizeof (MIG_CONTENT));
  1056. if (result) {
  1057. CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
  1058. if ((ObjectContent->MemoryContent.ContentSize != 0) &&
  1059. (ObjectContent->MemoryContent.ContentBytes != NULL)
  1060. ) {
  1061. // convert Mapped Drive content
  1062. result->MemoryContent.ContentBytes = IsmGetMemory (sizeof (NETSHARE_DATAW));
  1063. if (result->MemoryContent.ContentBytes) {
  1064. DirectDbcsToUnicodeN (
  1065. ((PNETSHARE_DATAW)result->MemoryContent.ContentBytes)->sharePath,
  1066. ((PNETSHARE_DATAA)ObjectContent->MemoryContent.ContentBytes)->sharePath,
  1067. MAX_PATH + 1
  1068. );
  1069. result->MemoryContent.ContentSize = sizeof (NETSHARE_DATAW);
  1070. }
  1071. }
  1072. }
  1073. return result;
  1074. }
  1075. PMIG_CONTENT
  1076. ConvertNetShareContentToAnsi (
  1077. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1078. IN PMIG_CONTENT ObjectContent
  1079. )
  1080. {
  1081. PMIG_CONTENT result = NULL;
  1082. if (!ObjectContent) {
  1083. return result;
  1084. }
  1085. if (ObjectContent->ContentInFile) {
  1086. return result;
  1087. }
  1088. result = IsmGetMemory (sizeof (MIG_CONTENT));
  1089. if (result) {
  1090. CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
  1091. if ((ObjectContent->MemoryContent.ContentSize != 0) &&
  1092. (ObjectContent->MemoryContent.ContentBytes != NULL)
  1093. ) {
  1094. // convert Mapped Drive content
  1095. result->MemoryContent.ContentBytes = IsmGetMemory (sizeof (NETSHARE_DATAA));
  1096. if (result->MemoryContent.ContentBytes) {
  1097. DirectUnicodeToDbcsN (
  1098. ((PNETSHARE_DATAA)result->MemoryContent.ContentBytes)->sharePath,
  1099. ((PNETSHARE_DATAW)ObjectContent->MemoryContent.ContentBytes)->sharePath,
  1100. MAX_PATH + 1
  1101. );
  1102. result->MemoryContent.ContentSize = sizeof (NETSHARE_DATAA);
  1103. }
  1104. }
  1105. }
  1106. return result;
  1107. }
  1108. BOOL
  1109. FreeConvertedNetShareContent (
  1110. IN PMIG_CONTENT ObjectContent
  1111. )
  1112. {
  1113. if (!ObjectContent) {
  1114. return TRUE;
  1115. }
  1116. if (ObjectContent->MemoryContent.ContentBytes) {
  1117. IsmReleaseMemory (ObjectContent->MemoryContent.ContentBytes);
  1118. }
  1119. IsmReleaseMemory (ObjectContent);
  1120. return TRUE;
  1121. }