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.

4033 lines
89 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. api.c
  5. Abstract:
  6. reintegration functions
  7. Contents:
  8. Author:
  9. Shishir Pardikar
  10. Environment:
  11. Win32 (user-mode) DLL
  12. Revision History:
  13. 4/24/97 Created shishirp
  14. --*/
  15. #include "pch.h"
  16. #ifdef CSC_ON_NT
  17. #include <winioctl.h>
  18. #define UNICODE
  19. #endif //CSC_ON_NT
  20. #include "shdcom.h"
  21. #include "shdsys.h"
  22. #include "reint.h"
  23. #include "utils.h"
  24. #include "resource.h"
  25. #include "strings.h"
  26. // this sets flags in a couple of headers to not include some defs.
  27. #define REINT
  28. #include "lib3.h"
  29. #include "cscapi.h"
  30. //
  31. // Defines/structures
  32. //
  33. #define SHADOW_FIND_SIGNATURE 0x61626162 // abab
  34. #define FLAG_SHADOW_FIND_TERMINATED 0x00000001
  35. typedef struct tagSHADOW_FIND
  36. {
  37. DWORD dwSignature; // for validation
  38. DWORD dwFlags;
  39. HANDLE hShadowDB;
  40. ULONG ulPrincipalID;
  41. CSC_ENUMCOOKIE uEnumCookie;
  42. }
  43. SHADOW_FIND, *LPSHADOW_FIND;
  44. typedef struct tagMST_LIST
  45. {
  46. struct tagMST_LIST *lpNext;
  47. HSHADOW hDir;
  48. } MST_LIST, *LPMST_LIST;
  49. typedef struct tagMOVE_SUBTREE
  50. {
  51. DWORD dwFlags;
  52. DWORD cntFail;
  53. HSHARE hShareTo;
  54. LPCTSTR lptzSource;
  55. LPCTSTR lptzDestination;
  56. LPMST_LIST lpTos;
  57. MST_LIST sTos;
  58. SHADOWINFO sSI;
  59. WIN32_FIND_DATA sFind32;
  60. } MOVE_SUBTREE, *LPMOVE_SUBTREE;
  61. #define MST_REPLACE_IF_EXISTS 0x00000001
  62. #define MST_SHARE_MARKED_DIRTY 0x00000002
  63. #define MST_MARK_AS_LOCAL 0x00000004
  64. typedef struct tagSET_SUBTREE_STATUS
  65. {
  66. DWORD dwFlags;
  67. ULONG uStatus;
  68. ULONG uOp;
  69. } SET_SUBTREE_STATUS, *LPSET_SUBTREE_STATUS;
  70. #define EDS_FLAG_ERROR_ENCOUNTERED 0x00000001
  71. typedef struct tagENCRYPT_DECRYPT_SUBTREE
  72. {
  73. DWORD dwFlags;
  74. BOOL fEncrypt;
  75. LPCSCPROCW lpfnEnumProgress;
  76. DWORD_PTR dwContext;
  77. DWORD dwEndingNameSpaceVersion;
  78. }ENCRYPT_DECRYPT_SUBTREE, *LPENCRYPT_DECRYPT_SUBTREE;
  79. BOOL
  80. CheckCSCAccessForThread(
  81. HSHADOW hDir,
  82. HSHADOW hShadow,
  83. BOOL fWrite
  84. );
  85. int
  86. MoveSubtree(
  87. HANDLE hShadowDB,
  88. LPSECURITYINFO pShareSecurityInfo,
  89. LPTSTR lptzFullPath,
  90. DWORD dwCallbackReason,
  91. WIN32_FIND_DATA *lpFind32,
  92. SHADOWINFO *lpSI,
  93. LPMOVE_SUBTREE lpMst
  94. );
  95. int
  96. SetSubtreeStatus(
  97. HANDLE hShadowDB,
  98. LPSECURITYINFO pShareSecurityInfo,
  99. LPTSTR lptzFullPath,
  100. DWORD dwCallbackReason,
  101. WIN32_FIND_DATA *lpFind32,
  102. SHADOWINFO *lpSI,
  103. LPSET_SUBTREE_STATUS lpSss
  104. );
  105. int
  106. EncryptDecryptSubtree(
  107. HANDLE hShadowDB,
  108. LPSECURITYINFO pShareSecurityInfo,
  109. LPTSTR lptzFullPath,
  110. DWORD dwCallbackReason,
  111. WIN32_FIND_DATA *lpFind32,
  112. SHADOWINFO *lpSI,
  113. LPENCRYPT_DECRYPT_SUBTREE lpEds
  114. );
  115. BOOL
  116. UncPathToDfsPath(
  117. PWCHAR UncPath,
  118. PWCHAR DfsPath,
  119. ULONG cbLen);
  120. BOOL
  121. IsPersonal(VOID);
  122. //
  123. // local data
  124. //
  125. static TCHAR vszStarDotStar[] = _TEXT("*.*");
  126. static TCHAR vszStar[] = _TEXT("*");
  127. static TCHAR vszPrefix[] = _TEXT("CSC");
  128. AssertData;
  129. AssertError;
  130. //
  131. // functions
  132. //
  133. BOOL
  134. WINAPI
  135. CSCIsCSCEnabled(
  136. VOID
  137. )
  138. /*++
  139. Routine Description:
  140. Arguments:
  141. Returns:
  142. Notes:
  143. --*/
  144. {
  145. unsigned ulSwitch = SHADOW_SWITCH_SHADOWING;
  146. if(ShadowSwitches(INVALID_HANDLE_VALUE, &ulSwitch, SHADOW_SWITCH_GET_STATE))
  147. {
  148. return((ulSwitch & SHADOW_SWITCH_SHADOWING)!=0);
  149. }
  150. return FALSE;
  151. }
  152. BOOL
  153. WINAPI
  154. CSCGetSpaceUsageA(
  155. LPSTR lptzLocation,
  156. DWORD dwSize,
  157. LPDWORD lpdwMaxSpaceHigh,
  158. LPDWORD lpdwMaxSpaceLow,
  159. LPDWORD lpdwCurrentSpaceHigh,
  160. LPDWORD lpdwCurrentSpaceLow,
  161. LPDWORD lpcntTotalFiles,
  162. LPDWORD lpcntTotalDirs
  163. )
  164. /*++
  165. Routine Description:
  166. Arguments:
  167. Returns:
  168. Notes:
  169. --*/
  170. {
  171. #ifdef UNICODE
  172. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  173. return (FALSE);
  174. #else
  175. SHADOWSTORE sST;
  176. WIN32_FIND_DATA sFind32;
  177. BOOL fRet = FALSE;
  178. DWORD dwLen;
  179. // NTRAID#455247-1/31/2000-shishirp parameter validation
  180. if (GetShadowDatabaseLocation(INVALID_HANDLE_VALUE, &sFind32))
  181. {
  182. memset(lptzLocation, 0, sizeof(dwSize));
  183. WideCharToMultiByte(CP_ACP, 0, sFind32.cFileName, wcslen(sFind32.cFileName), lptzLocation, dwSize, NULL, NULL);
  184. if (GetSpaceStats(INVALID_HANDLE_VALUE, &sST))
  185. {
  186. *lpdwMaxSpaceHigh = 0;
  187. *lpdwMaxSpaceLow = sST.sMax.ulSize;
  188. *lpdwCurrentSpaceHigh = 0;
  189. *lpdwCurrentSpaceLow = sST.sCur.ulSize;
  190. *lpcntTotalFiles = sST.sCur.ucntFiles;
  191. *lpcntTotalFiles = sST.sCur.ucntDirs;
  192. fRet = TRUE;
  193. }
  194. }
  195. return fRet;
  196. #endif
  197. }
  198. BOOL
  199. WINAPI
  200. CSCGetSpaceUsageW(
  201. LPTSTR lptzLocation,
  202. DWORD dwSize,
  203. LPDWORD lpdwMaxSpaceHigh,
  204. LPDWORD lpdwMaxSpaceLow,
  205. LPDWORD lpdwCurrentSpaceHigh,
  206. LPDWORD lpdwCurrentSpaceLow,
  207. LPDWORD lpcntTotalFiles,
  208. LPDWORD lpcntTotalDirs
  209. )
  210. /*++
  211. Routine Description:
  212. Arguments:
  213. Returns:
  214. Notes:
  215. --*/
  216. {
  217. #ifndef UNICODE
  218. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  219. return (FALSE);
  220. #else
  221. SHADOWSTORE sST;
  222. WIN32_FIND_DATA sFind32;
  223. BOOL fRet = FALSE;
  224. // NTRAID#455247-1/31/2000-shishirp parameter validation
  225. if (GetShadowDatabaseLocation(INVALID_HANDLE_VALUE, &sFind32))
  226. {
  227. memset(lptzLocation, 0, dwSize);
  228. wcsncpy(lptzLocation, sFind32.cFileName, dwSize/sizeof(USHORT)-1);
  229. if (GetSpaceStats(INVALID_HANDLE_VALUE, &sST))
  230. {
  231. *lpdwMaxSpaceHigh = 0;
  232. *lpdwMaxSpaceLow = sST.sMax.ulSize;
  233. *lpdwCurrentSpaceHigh = 0;
  234. *lpdwCurrentSpaceLow = sST.sCur.ulSize;
  235. *lpcntTotalFiles = sST.sCur.ucntFiles;
  236. *lpcntTotalDirs = sST.sCur.ucntDirs;
  237. fRet = TRUE;
  238. }
  239. }
  240. return fRet;
  241. #endif
  242. }
  243. BOOL
  244. WINAPI
  245. CSCSetMaxSpace(
  246. DWORD nFileSizeHigh,
  247. DWORD nFileSizeLow
  248. )
  249. /*++
  250. Routine Description:
  251. Arguments:
  252. Returns:
  253. Notes:
  254. --*/
  255. {
  256. int iRet;
  257. // 2GB is our limit
  258. if ((nFileSizeHigh)||(nFileSizeLow > 0x7fffffff))
  259. {
  260. SetLastError(ERROR_INVALID_PARAMETER);
  261. return FALSE;
  262. }
  263. iRet = SetMaxShadowSpace(INVALID_HANDLE_VALUE, (long)nFileSizeHigh, (long)nFileSizeLow);
  264. if (iRet<0)
  265. {
  266. SetLastError(ERROR_INTERNAL_ERROR);
  267. }
  268. return (iRet >= 1);
  269. }
  270. BOOL
  271. CSCPinFileInternal(
  272. LPCTSTR lpszFileName,
  273. DWORD dwHintFlags,
  274. LPDWORD lpdwStatus,
  275. LPDWORD lpdwPinCount,
  276. LPDWORD lpdwHintFlags
  277. )
  278. /*++
  279. Routine Description:
  280. Arguments:
  281. Returns:
  282. Notes:
  283. --*/
  284. {
  285. WIN32_FIND_DATA sFind32;
  286. SHADOWINFO sSI;
  287. BOOL fCreated, fRet = FALSE;
  288. DWORD dwError = ERROR_GEN_FAILURE;
  289. // NTRAID#455247-1/31/2000-shishirp parameter validation !!!!
  290. if (BeginInodeTransactionHSHADOW())
  291. {
  292. if(FindCreateShadowFromPath(lpszFileName, TRUE, &sFind32, &sSI, &fCreated))
  293. {
  294. sSI.ulHintFlags = dwHintFlags;
  295. fRet = (AddHintFromInode( INVALID_HANDLE_VALUE,
  296. sSI.hDir,
  297. sSI.hShadow,
  298. &(sSI.ulHintPri),
  299. &(sSI.ulHintFlags)
  300. ) != 0);
  301. if (fRet)
  302. {
  303. if (lpdwStatus)
  304. {
  305. *lpdwStatus = sSI.uStatus;
  306. }
  307. if (lpdwPinCount)
  308. {
  309. *lpdwPinCount = sSI.ulHintPri;
  310. }
  311. if (lpdwHintFlags)
  312. {
  313. *lpdwHintFlags = sSI.ulHintFlags;
  314. }
  315. }
  316. else
  317. {
  318. dwError = ERROR_INVALID_FUNCTION;
  319. }
  320. }
  321. else
  322. {
  323. dwError = GetLastError();
  324. }
  325. EndInodeTransactionHSHADOW();
  326. }
  327. if (!fRet)
  328. {
  329. Assert(dwError != ERROR_SUCCESS);
  330. SetLastError(dwError);
  331. }
  332. return fRet;
  333. }
  334. BOOL
  335. CSCUnpinFileInternal(
  336. LPCTSTR lpszFileName,
  337. IN DWORD dwHintFlags,
  338. LPDWORD lpdwStatus,
  339. LPDWORD lpdwPinCount,
  340. LPDWORD lpdwHintFlags
  341. )
  342. /*++
  343. Routine Description:
  344. Arguments:
  345. Returns:
  346. Notes:
  347. --*/
  348. {
  349. WIN32_FIND_DATA sFind32;
  350. SHADOWINFO sSI;
  351. BOOL fRet = FALSE;
  352. DWORD dwError = ERROR_GEN_FAILURE;
  353. // NTRAID#455247-1/31/2000-shishirp parameter validation !!!!
  354. if (BeginInodeTransactionHSHADOW())
  355. {
  356. if(FindCreateShadowFromPath(lpszFileName, FALSE, &sFind32, &sSI, NULL))
  357. {
  358. sSI.ulHintFlags = dwHintFlags;
  359. fRet = (DeleteHintFromInode( INVALID_HANDLE_VALUE,
  360. sSI.hDir,
  361. sSI.hShadow,
  362. &(sSI.ulHintPri),
  363. &(sSI.ulHintFlags)
  364. ) != 0);
  365. if (fRet)
  366. {
  367. if (lpdwStatus)
  368. {
  369. *lpdwStatus = sSI.uStatus;
  370. }
  371. if (lpdwPinCount)
  372. {
  373. *lpdwPinCount = sSI.ulHintPri;
  374. }
  375. if (lpdwHintFlags)
  376. {
  377. *lpdwHintFlags = sSI.ulHintFlags;
  378. }
  379. }
  380. else
  381. {
  382. dwError = ERROR_INVALID_FUNCTION;
  383. }
  384. }
  385. else
  386. {
  387. dwError = GetLastError();
  388. }
  389. EndInodeTransactionHSHADOW();
  390. }
  391. if (!fRet)
  392. {
  393. SetLastError(dwError);
  394. }
  395. return fRet;
  396. }
  397. BOOL
  398. CSCQueryFileStatusInternal(
  399. LPCTSTR lpszFileName,
  400. LPDWORD lpdwStatus,
  401. LPDWORD lpdwPinCount,
  402. LPDWORD lpdwHintFlags,
  403. LPDWORD lpdwUserPerms,
  404. LPDWORD lpdwOtherPerms
  405. )
  406. /*++
  407. Routine Description:
  408. Arguments:
  409. Returns:
  410. Notes:
  411. --*/
  412. {
  413. WIN32_FIND_DATA sFind32;
  414. SHADOWINFO sSI;
  415. // NTRAID#455247-1/31/2000-shishirp parameter validation !!!!
  416. if (FindCreateShadowFromPath(lpszFileName, FALSE, &sFind32, &sSI, NULL) != TRUE)
  417. return FALSE;
  418. if (lpdwStatus != NULL) {
  419. *lpdwStatus = sSI.uStatus;
  420. // return accessmask for files or the root
  421. if ((sSI.uStatus & SHADOW_IS_FILE)||(!sSI.hDir)) {
  422. if (sSI.hShadow) {
  423. ULONG ulPrincipalID;
  424. if (!GetCSCPrincipalID(&ulPrincipalID))
  425. ulPrincipalID = CSC_GUEST_PRINCIPAL_ID;
  426. GetCSCAccessMaskForPrincipalEx(
  427. ulPrincipalID,
  428. sSI.hDir,
  429. sSI.hShadow,
  430. lpdwStatus,
  431. lpdwUserPerms,
  432. lpdwOtherPerms);
  433. Assert((*lpdwStatus & ~FLAG_CSC_ACCESS_MASK) == sSI.uStatus);
  434. if (lpdwUserPerms != NULL && lpdwOtherPerms != NULL) {
  435. ULONG i;
  436. ULONG GuestIdx = CSC_MAXIMUM_NUMBER_OF_CACHED_PRINCIPAL_IDS;
  437. ULONG UserIdx = CSC_MAXIMUM_NUMBER_OF_CACHED_PRINCIPAL_IDS;
  438. SECURITYINFO rgsSecurityInfo[CSC_MAXIMUM_NUMBER_OF_CACHED_PRINCIPAL_IDS];
  439. _TCHAR tchBuff[MAX_SERVER_SHARE_NAME_FOR_CSC];
  440. ULONG nRet = 0;
  441. DWORD dwDummy;
  442. WIN32_FIND_DATA sFind32;
  443. SHADOWINFO sSI2;
  444. BOOL fDone = FALSE;
  445. // DbgPrint("CSCQueryFileStatusInternal(%ws)\n", lpszFileName);
  446. if (lstrlen(lpszFileName) >= MAX_SERVER_SHARE_NAME_FOR_CSC)
  447. goto AllDone;
  448. lstrcpy(tchBuff, lpszFileName);
  449. if (!LpBreakPath(tchBuff, TRUE, &fDone))
  450. goto AllDone;
  451. // DbgPrint(" tchBuff=%ws\n", tchBuff);
  452. if (!FindCreateShadowFromPath(tchBuff, FALSE, &sFind32, &sSI2, NULL))
  453. goto AllDone;
  454. // DbgPrint("CSCQueryFileStatusInternal: hShare=0x%x,hShadow=0x%x,hDir=0x%x\n",
  455. // sSI2.hShare,
  456. // sSI2.hShadow,
  457. // sSI2.hDir);
  458. dwDummy = sizeof(rgsSecurityInfo);
  459. nRet = GetSecurityInfoForCSC(
  460. INVALID_HANDLE_VALUE,
  461. 0,
  462. sSI2.hShadow,
  463. rgsSecurityInfo,
  464. &dwDummy);
  465. // DbgPrint(" GetSecurityInfoForCSC returned %d\n", nRet);
  466. if (nRet == 0)
  467. goto AllDone;
  468. //
  469. // Find the user's and guest's entries
  470. //
  471. for (i = 0; i < CSC_MAXIMUM_NUMBER_OF_CACHED_PRINCIPAL_IDS; i++) {
  472. if (rgsSecurityInfo[i].ulPrincipalID == ulPrincipalID)
  473. UserIdx = i;
  474. if (rgsSecurityInfo[i].ulPrincipalID == CSC_GUEST_PRINCIPAL_ID)
  475. GuestIdx = i;
  476. }
  477. if (GuestIdx < CSC_MAXIMUM_NUMBER_OF_CACHED_PRINCIPAL_IDS) {
  478. if (UserIdx >= CSC_MAXIMUM_NUMBER_OF_CACHED_PRINCIPAL_IDS)
  479. UserIdx = GuestIdx;
  480. *lpdwUserPerms &= rgsSecurityInfo[UserIdx].ulPermissions;
  481. *lpdwOtherPerms &= rgsSecurityInfo[GuestIdx].ulPermissions;
  482. // DbgPrint("UserPerms=0x%x,OtherPerms=0x%x\n",
  483. // *lpdwUserPerms,
  484. // *lpdwOtherPerms);
  485. }
  486. }
  487. }
  488. }
  489. }
  490. AllDone:
  491. if (lpdwPinCount) {
  492. *lpdwPinCount = sSI.ulHintPri;
  493. }
  494. if (lpdwHintFlags) {
  495. *lpdwHintFlags = sSI.ulHintFlags;
  496. }
  497. return TRUE;
  498. }
  499. HANDLE
  500. CSCFindFirstFileInternal(
  501. LPCTSTR lpszFileName,
  502. ULONG ulPrincipalID,
  503. WIN32_FIND_DATA *lpFind32,
  504. LPDWORD lpdwStatus,
  505. LPDWORD lpdwPinCount,
  506. LPDWORD lpdwHintFlags,
  507. FILETIME *lpOrgFileTime
  508. )
  509. /*++
  510. Routine Description:
  511. Arguments:
  512. Returns:
  513. Notes:
  514. --*/
  515. {
  516. SHADOWINFO sSI;
  517. BOOL fRet = FALSE;
  518. LPSHADOW_FIND lpShadowFind = NULL;
  519. // NTRAID#455247-1/31/2000-shishirp parameter validation !!!!
  520. if (lpszFileName && *lpszFileName)
  521. {
  522. fRet = FindCreateShadowFromPath(
  523. lpszFileName, // UNC path
  524. FALSE, // don't create
  525. lpFind32,
  526. &sSI,
  527. NULL);
  528. if (fRet && !sSI.hShadow)
  529. {
  530. // a situation where, the share is connected but it's entry is
  531. // not in the database
  532. fRet = FALSE;
  533. }
  534. }
  535. else
  536. {
  537. memset(&sSI, 0, sizeof(sSI)); // sSI.hShadow is 0 => we are enumerating all shares
  538. lpFind32->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
  539. fRet = TRUE;
  540. }
  541. if (fRet)
  542. {
  543. fRet = FALSE;
  544. // Found the shadow
  545. if (lpShadowFind = AllocMem(sizeof(SHADOW_FIND)))
  546. {
  547. lpShadowFind->dwSignature = SHADOW_FIND_SIGNATURE;
  548. lpShadowFind->hShadowDB = INVALID_HANDLE_VALUE;
  549. if (ulPrincipalID != CSC_INVALID_PRINCIPAL_ID)
  550. {
  551. lpShadowFind->ulPrincipalID = ulPrincipalID;
  552. }
  553. else
  554. {
  555. if (!GetCSCPrincipalID(&lpShadowFind->ulPrincipalID))
  556. {
  557. lpShadowFind->ulPrincipalID = CSC_GUEST_PRINCIPAL_ID;
  558. }
  559. }
  560. if (!(lpFind32->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  561. {
  562. lpShadowFind->dwFlags |= FLAG_SHADOW_FIND_TERMINATED;
  563. fRet = TRUE;
  564. }
  565. else
  566. {
  567. // lpShadowFind->hShadowDB = OpenShadowDatabaseIO();
  568. // if (lpShadowFind->hShadowDB != INVALID_HANDLE_VALUE)
  569. {
  570. #ifndef CSC_ON_NT
  571. lstrcpy(lpFind32->cFileName, vszStarDotStar);
  572. #else
  573. lstrcpy(lpFind32->cFileName, vszStar);
  574. #endif
  575. if(FindOpenShadow(
  576. lpShadowFind->hShadowDB,
  577. sSI.hShadow,
  578. FINDOPEN_SHADOWINFO_ALL,
  579. lpFind32,
  580. &sSI
  581. ))
  582. {
  583. lpShadowFind->uEnumCookie = sSI.uEnumCookie;
  584. fRet = TRUE;
  585. }
  586. }
  587. }
  588. }
  589. }
  590. if (!fRet)
  591. {
  592. if (lpShadowFind)
  593. {
  594. if (lpShadowFind->hShadowDB != INVALID_HANDLE_VALUE)
  595. {
  596. CloseShadowDatabaseIO(lpShadowFind->hShadowDB);
  597. }
  598. FreeMem(lpShadowFind);
  599. }
  600. EndInodeTransactionHSHADOW();
  601. return (INVALID_HANDLE_VALUE);
  602. }
  603. else
  604. {
  605. if (lpdwStatus)
  606. {
  607. *lpdwStatus = (DWORD)(sSI.uStatus);
  608. // return accessmask for files or the root
  609. if ((sSI.uStatus & SHADOW_IS_FILE)||(!sSI.hDir))
  610. {
  611. GetCSCAccessMaskForPrincipal(lpShadowFind->ulPrincipalID, sSI.hDir, sSI.hShadow, lpdwStatus);
  612. Assert((*lpdwStatus & ~FLAG_CSC_ACCESS_MASK) == sSI.uStatus);
  613. }
  614. }
  615. if (lpdwPinCount)
  616. {
  617. *lpdwPinCount = (DWORD)(sSI.ulHintPri);
  618. }
  619. if (lpdwHintFlags)
  620. {
  621. *lpdwHintFlags = sSI.ulHintFlags;
  622. }
  623. if (lpOrgFileTime)
  624. {
  625. *lpOrgFileTime = lpFind32->ftLastAccessTime;
  626. }
  627. return ((HANDLE)lpShadowFind);
  628. }
  629. }
  630. BOOL
  631. CSCFindNextFileInternal(
  632. HANDLE hFind,
  633. WIN32_FIND_DATA *lpFind32,
  634. LPDWORD lpdwStatus,
  635. LPDWORD lpdwPinCount,
  636. LPDWORD lpdwHintFlags,
  637. FILETIME *lpOrgFileTime
  638. )
  639. /*++
  640. Routine Description:
  641. Arguments:
  642. Returns:
  643. Notes:
  644. --*/
  645. {
  646. LPSHADOW_FIND lpShadowFind = (LPSHADOW_FIND)hFind;
  647. BOOL fRet = FALSE;
  648. SHADOWINFO sSI;
  649. // validate parameters !!!!
  650. if (lpShadowFind->dwFlags & FLAG_SHADOW_FIND_TERMINATED)
  651. {
  652. SetLastError(ERROR_NO_MORE_FILES);
  653. return FALSE;
  654. }
  655. else
  656. {
  657. if (!FindNextShadow( lpShadowFind->hShadowDB,
  658. lpShadowFind->uEnumCookie,
  659. lpFind32,
  660. &sSI
  661. ))
  662. {
  663. lpShadowFind->dwFlags |= FLAG_SHADOW_FIND_TERMINATED;
  664. SetLastError(ERROR_NO_MORE_FILES);
  665. }
  666. else
  667. {
  668. if (lpdwStatus)
  669. {
  670. *lpdwStatus = (DWORD)(sSI.uStatus);
  671. // return accessmask for files or the root
  672. if ((sSI.uStatus & SHADOW_IS_FILE)||(!sSI.hDir))
  673. {
  674. GetCSCAccessMaskForPrincipal(lpShadowFind->ulPrincipalID, sSI.hDir, sSI.hShadow, lpdwStatus);
  675. Assert((*lpdwStatus & ~FLAG_CSC_ACCESS_MASK) == sSI.uStatus);
  676. }
  677. }
  678. if (lpdwPinCount)
  679. {
  680. *lpdwPinCount = (DWORD)(sSI.ulHintPri);
  681. }
  682. if (lpdwHintFlags)
  683. {
  684. *lpdwHintFlags = sSI.ulHintFlags;
  685. }
  686. if (lpOrgFileTime)
  687. {
  688. *lpOrgFileTime = lpFind32->ftLastAccessTime;
  689. }
  690. fRet = TRUE;
  691. }
  692. }
  693. return (fRet);
  694. }
  695. BOOL
  696. WINAPI
  697. CSCFindClose(
  698. HANDLE hFind
  699. )
  700. /*++
  701. Routine Description:
  702. Arguments:
  703. Returns:
  704. Notes:
  705. --*/
  706. {
  707. LPSHADOW_FIND lpShadowFind = (LPSHADOW_FIND)hFind;
  708. if (lpShadowFind->uEnumCookie)
  709. {
  710. // don't check any errors
  711. FindCloseShadow(lpShadowFind->hShadowDB, lpShadowFind->uEnumCookie);
  712. }
  713. if (lpShadowFind->hShadowDB != INVALID_HANDLE_VALUE)
  714. {
  715. CloseShadowDatabaseIO(lpShadowFind->hShadowDB);
  716. }
  717. FreeMem(lpShadowFind);
  718. return (TRUE);
  719. }
  720. BOOL
  721. CSCDeleteInternal(
  722. LPCTSTR lpszName
  723. )
  724. /*++
  725. Routine Description:
  726. Arguments:
  727. Returns:
  728. Notes:
  729. --*/
  730. {
  731. WIN32_FIND_DATA sFind32;
  732. SHADOWINFO sSI;
  733. BOOL fRet = FALSE;
  734. DWORD dwError = ERROR_GEN_FAILURE;
  735. DWORD dwStatus = 0;
  736. BOOL DoDelete = FALSE;
  737. // NTRAID#455247 -1/31/2000-shishirp parameter validation !!!!
  738. ReintKdPrint(API, ("Delete %ls\r\n", lpszName));
  739. if(CSCQueryFileStatus(lpszName, &dwStatus, NULL, NULL))
  740. {
  741. // Shouls check if the user has the permission to delete this file - Bug 524237
  742. if(!(FLAG_CSC_COPY_STATUS_IS_FILE & dwStatus) || //is directory or
  743. (((dwStatus & FLAG_CSC_GUEST_ACCESS_MASK) & // the guest has write permission
  744. FLAG_CSC_WRITE_ACCESS << FLAG_CSC_GUEST_ACCESS_SHIFT_COUNT) ||
  745. ((dwStatus & FLAG_CSC_USER_ACCESS_MASK) & // or the user has write permission
  746. FLAG_CSC_WRITE_ACCESS << FLAG_CSC_USER_ACCESS_SHIFT_COUNT)))
  747. {
  748. if (BeginInodeTransactionHSHADOW())
  749. {
  750. if(FindCreateShadowFromPath(lpszName, FALSE, &sFind32, &sSI, NULL))
  751. {
  752. ReintKdPrint(API, ("Delete Inode %x %x\r\n", sSI.hDir, sSI.hShadow));
  753. if (DeleteShadow(INVALID_HANDLE_VALUE, sSI.hDir, sSI.hShadow))
  754. {
  755. fRet = TRUE;
  756. }
  757. else
  758. {
  759. dwError = ERROR_ACCESS_DENIED;
  760. }
  761. }
  762. else
  763. {
  764. dwError = GetLastError();
  765. }
  766. EndInodeTransactionHSHADOW();
  767. }
  768. }
  769. else
  770. {
  771. dwError = ERROR_ACCESS_DENIED;
  772. }
  773. }
  774. if (!fRet)
  775. {
  776. SetLastError(dwError);
  777. }
  778. return fRet;
  779. }
  780. BOOL
  781. CSCFillSparseFilesInternal(
  782. IN LPCTSTR lpszShareOrFileName,
  783. IN BOOL fFullSync,
  784. IN LPCSCPROC lpfnFillProgress,
  785. IN DWORD_PTR dwContext
  786. )
  787. /*++
  788. Routine Description:
  789. Arguments:
  790. Returns:
  791. Notes:
  792. --*/
  793. {
  794. WIN32_FIND_DATA sFind32;
  795. SHADOWINFO sSI;
  796. DWORD dwError = ERROR_INVALID_PARAMETER, dwRet;
  797. LPCOPYPARAMS lpCP = NULL;
  798. ULONG ulPrincipalID;
  799. if (!GetCSCPrincipalID(&ulPrincipalID))
  800. {
  801. ulPrincipalID = CSC_GUEST_PRINCIPAL_ID;
  802. }
  803. if(FindCreateShadowFromPath(lpszShareOrFileName, FALSE, &sFind32, &sSI, NULL))
  804. {
  805. if (!sSI.hDir)
  806. {
  807. dwError = NO_ERROR;
  808. // if this is a share
  809. dwRet = (*lpfnFillProgress)(
  810. lpszShareOrFileName,
  811. sSI.uStatus,
  812. sSI.ulHintFlags,
  813. sSI.ulHintPri,
  814. &sFind32,
  815. CSCPROC_REASON_BEGIN,
  816. 0,
  817. 0,
  818. dwContext
  819. );
  820. if (dwRet == CSCPROC_RETURN_CONTINUE)
  821. {
  822. AttemptCacheFill(sSI.hShare, DO_ALL, fFullSync, ulPrincipalID, lpfnFillProgress, dwContext);
  823. }
  824. else
  825. {
  826. if (dwRet == CSCPROC_RETURN_ABORT)
  827. {
  828. dwError = ERROR_OPERATION_ABORTED;
  829. }
  830. }
  831. (*lpfnFillProgress)(
  832. lpszShareOrFileName,
  833. sSI.uStatus,
  834. sSI.ulHintFlags,
  835. sSI.ulHintPri,
  836. &sFind32,
  837. CSCPROC_REASON_END,
  838. 0,
  839. 0,
  840. dwContext
  841. );
  842. }
  843. else if (!(sFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  844. {
  845. BOOL fStalenessCheck;
  846. dwError = NO_ERROR;
  847. fStalenessCheck = (fFullSync || (sSI.uStatus & SHADOW_STALE));
  848. if (fStalenessCheck)
  849. {
  850. if (!(lpCP = LpAllocCopyParams()))
  851. {
  852. dwError = GetLastError();
  853. Assert(dwError != NO_ERROR);
  854. }
  855. else if(!GetUNCPath(INVALID_HANDLE_VALUE, sSI.hShare, sSI.hDir, sSI.hShadow, lpCP))
  856. {
  857. Assert(lpCP);
  858. FreeCopyParams(lpCP);
  859. dwError = GetLastError();
  860. Assert(dwError != NO_ERROR);
  861. }
  862. }
  863. if ((dwError == NO_ERROR) &&
  864. (fStalenessCheck || (sSI.uStatus & SHADOW_SPARSE))) {
  865. dwError = DoSparseFill( INVALID_HANDLE_VALUE,
  866. (LPTSTR)lpszShareOrFileName,
  867. NULL,
  868. &sSI,
  869. &sFind32,
  870. lpCP,
  871. fStalenessCheck,
  872. ulPrincipalID,
  873. lpfnFillProgress,
  874. dwContext);
  875. }
  876. if (lpCP)
  877. {
  878. FreeCopyParams(lpCP);
  879. lpCP = NULL;
  880. }
  881. }
  882. }
  883. else
  884. {
  885. dwError = GetLastError();
  886. }
  887. if (dwError != NO_ERROR)
  888. {
  889. SetLastError(dwError);
  890. return FALSE;
  891. }
  892. return TRUE;
  893. }
  894. BOOL
  895. CSCMergeShareInternal(
  896. IN LPCTSTR lpszShareName,
  897. IN LPCSCPROC lpfnMergeProgress,
  898. IN DWORD_PTR dwContext
  899. )
  900. /*++
  901. Routine Description:
  902. Arguments:
  903. Returns:
  904. Notes:
  905. --*/
  906. {
  907. WIN32_FIND_DATA sFind32;
  908. SHADOWINFO sSI;
  909. int cntDriveMapped = 0;
  910. BOOL fTransitionedToOnline = FALSE, fDone=FALSE;
  911. _TCHAR tchBuff[MAX_SERVER_SHARE_NAME_FOR_CSC];
  912. DWORD dwError = ERROR_SUCCESS;
  913. ULONG ulPrincipalID;
  914. if (!GetCSCPrincipalID(&ulPrincipalID))
  915. {
  916. ulPrincipalID = CSC_GUEST_PRINCIPAL_ID;
  917. }
  918. if (lstrlen(lpszShareName) >= MAX_SERVER_SHARE_NAME_FOR_CSC)
  919. {
  920. SetLastError(ERROR_INVALID_PARAMETER);
  921. return FALSE;
  922. }
  923. lstrcpy(tchBuff, lpszShareName);
  924. if (!LpBreakPath(tchBuff, TRUE, &fDone) && !fDone)
  925. {
  926. SetLastError(ERROR_INVALID_PARAMETER);
  927. return FALSE;
  928. }
  929. if(FindCreateShadowFromPath(tchBuff, FALSE, &sFind32, &sSI, NULL))
  930. {
  931. fDone = ReintOneShare(sSI.hShare, sSI.hShadow, NULL, NULL, NULL, ulPrincipalID, lpfnMergeProgress, dwContext);
  932. if (!fDone)
  933. {
  934. dwError = GetLastError();
  935. }
  936. // TransitionShareToOnline(INVALID_HANDLE_VALUE, sSI.hShare);
  937. if (!fDone)
  938. {
  939. SetLastError(dwError);
  940. }
  941. return fDone;
  942. }
  943. return FALSE;
  944. }
  945. BOOL
  946. CSCCopyReplicaInternal(
  947. IN LPCTSTR lpszFullPath,
  948. OUT LPTSTR *lplpszLocalName
  949. )
  950. /*++
  951. Routine Description:
  952. Arguments:
  953. Returns:
  954. Notes:
  955. --*/
  956. {
  957. WIN32_FIND_DATA sFind32;
  958. SHADOWINFO sSI;
  959. BOOL fRet = FALSE;
  960. DWORD dwError = ERROR_GEN_FAILURE;
  961. if (BeginInodeTransactionHSHADOW())
  962. {
  963. if(FindCreateShadowFromPath(lpszFullPath, FALSE, &sFind32, &sSI, NULL))
  964. {
  965. if (sFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  966. {
  967. dwError = ERROR_INVALID_PARAMETER;
  968. goto bailout;
  969. }
  970. if (!CheckCSCAccessForThread(sSI.hDir, sSI.hShadow, FALSE))
  971. {
  972. dwError = GetLastError();
  973. goto bailout;
  974. }
  975. if (!(*lplpszLocalName = GetTempFileForCSC(NULL)))
  976. {
  977. goto bailout;
  978. }
  979. if(!CopyShadow(INVALID_HANDLE_VALUE, sSI.hDir, sSI.hShadow, *lplpszLocalName))
  980. {
  981. LocalFree(*lplpszLocalName);
  982. *lplpszLocalName = NULL;
  983. goto bailout;
  984. }
  985. fRet = TRUE;
  986. }
  987. else
  988. {
  989. dwError = GetLastError();
  990. }
  991. EndInodeTransactionHSHADOW();
  992. }
  993. bailout:
  994. if (!fRet)
  995. {
  996. SetLastError(dwError);
  997. }
  998. return fRet;
  999. }
  1000. BOOL
  1001. CSCEnumForStatsInternal(
  1002. IN LPCTSTR lpszShareName,
  1003. IN LPCSCPROC lpfnEnumProgress,
  1004. IN BOOL fPeruserInfo,
  1005. IN BOOL fUpdateShareReintBit,
  1006. IN DWORD_PTR dwContext
  1007. )
  1008. /*++
  1009. Routine Description:
  1010. Arguments:
  1011. Returns:
  1012. Notes:
  1013. --*/
  1014. {
  1015. WIN32_FIND_DATA sFind32;
  1016. SHADOWINFO sSI;
  1017. BOOL fRet = TRUE;
  1018. PQPARAMS sPQP;
  1019. HANDLE hShadowDB = INVALID_HANDLE_VALUE;
  1020. DWORD dwRet;
  1021. ULONG ulPrincipalID = CSC_INVALID_PRINCIPAL_ID;
  1022. if (lpszShareName)
  1023. {
  1024. if(!FindCreateShadowFromPath(lpszShareName, FALSE, &sFind32, &sSI, NULL))
  1025. {
  1026. fRet = FALSE;
  1027. }
  1028. }
  1029. else
  1030. {
  1031. sSI.hShare = 0;
  1032. }
  1033. if (fRet)
  1034. {
  1035. fRet = FALSE;
  1036. if ((hShadowDB = OpenShadowDatabaseIO())==INVALID_HANDLE_VALUE)
  1037. {
  1038. goto bailout;
  1039. }
  1040. if (lpfnEnumProgress)
  1041. {
  1042. dwRet = (*lpfnEnumProgress)(NULL, 0, 0, 0, NULL, CSCPROC_REASON_BEGIN, 0, 0, dwContext);
  1043. if (dwRet != CSCPROC_RETURN_CONTINUE )
  1044. {
  1045. goto bailout;
  1046. }
  1047. }
  1048. if (fPeruserInfo)
  1049. {
  1050. if (!GetCSCPrincipalID(&ulPrincipalID))
  1051. {
  1052. ulPrincipalID = CSC_GUEST_PRINCIPAL_ID;
  1053. }
  1054. }
  1055. memset(&sPQP, 0, sizeof(sPQP));
  1056. if(BeginPQEnum(hShadowDB, &sPQP) == 0) {
  1057. goto bailout;
  1058. }
  1059. do {
  1060. if(NextPriShadow(hShadowDB, &sPQP) == 0) {
  1061. break;
  1062. }
  1063. if (!sPQP.hShadow) {
  1064. break;
  1065. }
  1066. if (!sSI.hShare || (sSI.hShare == sPQP.hShare))
  1067. {
  1068. if (fPeruserInfo)
  1069. {
  1070. // return accessmask for files or the root
  1071. if ((sPQP.ulStatus & SHADOW_IS_FILE)||(!sPQP.hDir))
  1072. {
  1073. GetCSCAccessMaskForPrincipal(ulPrincipalID, sPQP.hDir, sPQP.hShadow, &sPQP.ulStatus);
  1074. }
  1075. }
  1076. if (lpfnEnumProgress)
  1077. {
  1078. // if we are enumerating for a particular share
  1079. // besides status, report whether file or directory and whether a root or a non-root
  1080. dwRet = (*lpfnEnumProgress)(NULL, sPQP.ulStatus & ~SHADOW_IS_FILE, sPQP.ulHintFlags, sPQP.ulHintPri, NULL, CSCPROC_REASON_MORE_DATA, (mShadowIsFile(sPQP.ulStatus) != 0), (sPQP.hDir==0), dwContext);
  1081. if (dwRet != CSCPROC_RETURN_CONTINUE )
  1082. {
  1083. break;
  1084. }
  1085. }
  1086. // if we are enumerating for a particular share
  1087. // then make sure that the share dirty bit matches with what we got on the
  1088. // actual files
  1089. if (fUpdateShareReintBit && sSI.hShare && (sSI.hShare == sPQP.hShare))
  1090. {
  1091. if (mShadowNeedReint(sPQP.ulStatus) && !(sSI.uStatus & SHARE_REINT))
  1092. {
  1093. if(SetShareStatus(hShadowDB, sSI.hShare, SHARE_REINT, SHADOW_FLAGS_OR))
  1094. {
  1095. sSI.uStatus |= SHARE_REINT;
  1096. }
  1097. }
  1098. }
  1099. }
  1100. } while (sPQP.uPos);
  1101. // Close the enumeration
  1102. EndPQEnum(hShadowDB, &sPQP);
  1103. if (lpfnEnumProgress)
  1104. {
  1105. dwRet = (*lpfnEnumProgress)(NULL, 0, 0, 0, NULL, CSCPROC_REASON_END, 0, 0, dwContext);
  1106. }
  1107. fRet = TRUE;
  1108. }
  1109. bailout:
  1110. if (hShadowDB != INVALID_HANDLE_VALUE)
  1111. {
  1112. CloseShadowDatabaseIO(hShadowDB);
  1113. }
  1114. return fRet;
  1115. }
  1116. BOOL
  1117. WINAPI
  1118. CSCPinFileA(
  1119. IN LPCSTR lpszFileName,
  1120. IN DWORD dwHintFlags,
  1121. IN LPDWORD lpdwStatus,
  1122. IN LPDWORD lpdwPinCount,
  1123. IN LPDWORD lpdwHintFlags
  1124. )
  1125. /*++
  1126. Routine Description:
  1127. Arguments:
  1128. Returns:
  1129. Notes:
  1130. --*/
  1131. {
  1132. #ifdef UNICODE
  1133. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1134. return (FALSE);
  1135. #else
  1136. return (CSCPinFileInternal(lpszFileName, dwHintFlags, lpdwStatus, lpdwPinCount, lpdwHintFlags));
  1137. #endif
  1138. }
  1139. BOOL
  1140. WINAPI
  1141. CSCUnpinFileA(
  1142. IN LPCSTR lpszFileName,
  1143. IN DWORD dwHintFlags,
  1144. IN LPDWORD lpdwStatus,
  1145. IN LPDWORD lpdwPinCount,
  1146. IN LPDWORD lpdwHintFlags
  1147. )
  1148. /*++
  1149. Routine Description:
  1150. Arguments:
  1151. Returns:
  1152. Notes:
  1153. --*/
  1154. {
  1155. #ifdef UNICODE
  1156. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1157. return (FALSE);
  1158. #else
  1159. return (CSCUnpinFileInternal(lpszFileName, dwHintFlags, lpdwStatus, lpdwPinCount, lpdwHintFlags));
  1160. #endif
  1161. }
  1162. BOOL
  1163. WINAPI
  1164. CSCQueryFileStatusA(
  1165. LPCSTR lpszFileName,
  1166. LPDWORD lpdwStatus,
  1167. LPDWORD lpdwPinCount,
  1168. LPDWORD lpdwHintFlags
  1169. )
  1170. /*++
  1171. Routine Description:
  1172. Arguments:
  1173. Returns:
  1174. Notes:
  1175. --*/
  1176. {
  1177. #ifdef UNICODE
  1178. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1179. return (FALSE);
  1180. #else
  1181. return (CSCQueryFileStatusInternal(
  1182. lpszFileName,
  1183. lpdwStatus,
  1184. lpdwPinCount,
  1185. lpdwHintFlags,
  1186. NULL,
  1187. NULL));
  1188. #endif
  1189. }
  1190. BOOL
  1191. WINAPI
  1192. CSCQueryFileStatusExA(
  1193. LPCSTR lpszFileName,
  1194. LPDWORD lpdwStatus,
  1195. LPDWORD lpdwPinCount,
  1196. LPDWORD lpdwHintFlags,
  1197. LPDWORD lpdwUserPerms,
  1198. LPDWORD lpdwOtherPerms
  1199. )
  1200. /*++
  1201. Routine Description:
  1202. Arguments:
  1203. Returns:
  1204. Notes:
  1205. --*/
  1206. {
  1207. #ifdef UNICODE
  1208. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1209. return (FALSE);
  1210. #else
  1211. return (CSCQueryFileStatusInternal(
  1212. lpszFileName,
  1213. lpdwStatus,
  1214. lpdwPinCount,
  1215. lpdwHintFlags,
  1216. lpdwUserPerms,
  1217. llpdwOtherPerms));
  1218. #endif
  1219. }
  1220. BOOL
  1221. WINAPI
  1222. CSCQueryShareStatusA(
  1223. LPCSTR lpszFileName,
  1224. LPDWORD lpdwStatus,
  1225. LPDWORD lpdwPinCount,
  1226. LPDWORD lpdwHintFlags,
  1227. LPDWORD lpdwUserPerms,
  1228. LPDWORD lpdwOtherPerms)
  1229. {
  1230. #ifdef UNICODE
  1231. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1232. return (FALSE);
  1233. #else
  1234. return (CSCQueryFileStatusInternal(
  1235. lpszFileName,
  1236. lpdwStatus,
  1237. lpdwPinCount,
  1238. lpdwHintFlags,
  1239. lpdwUserPerms,
  1240. llpdwOtherPerms));
  1241. #endif
  1242. }
  1243. HANDLE
  1244. WINAPI
  1245. CSCFindFirstFileA(
  1246. LPCSTR lpszFileName,
  1247. WIN32_FIND_DATA *lpFind32,
  1248. LPDWORD lpdwStatus,
  1249. LPDWORD lpdwPinCount,
  1250. LPDWORD lpdwHintFlags,
  1251. FILETIME *lpOrgFileTime
  1252. )
  1253. /*++
  1254. Routine Description:
  1255. Arguments:
  1256. Returns:
  1257. Notes:
  1258. --*/
  1259. {
  1260. #ifdef UNICODE
  1261. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1262. return (FALSE);
  1263. #else
  1264. return (CSCFindFirstFileInternal(
  1265. lpszFileName,
  1266. CSC_INVALID_PRINCIPAL_ID,
  1267. lpFind32,
  1268. lpdwStatus,
  1269. lpdwPinCount,
  1270. lpdwHintFlags,
  1271. lpOrgFileTime
  1272. ));
  1273. #endif
  1274. }
  1275. HANDLE
  1276. WINAPI
  1277. CSCFindFirstFileForSidA(
  1278. LPCSTR lpszFileName,
  1279. PSID pSid,
  1280. WIN32_FIND_DATA *lpFind32,
  1281. LPDWORD lpdwStatus,
  1282. LPDWORD lpdwPinCount,
  1283. LPDWORD lpdwHintFlags,
  1284. FILETIME *lpOrgFileTime
  1285. )
  1286. /*++
  1287. Routine Description:
  1288. Arguments:
  1289. Returns:
  1290. Notes:
  1291. --*/
  1292. {
  1293. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1294. return (FALSE);
  1295. }
  1296. BOOL
  1297. WINAPI
  1298. CSCFindNextFileA(
  1299. HANDLE hFind,
  1300. WIN32_FIND_DATA *lpFind32,
  1301. LPDWORD lpdwStatus,
  1302. LPDWORD lpdwPinCount,
  1303. LPDWORD lpdwHintFlags,
  1304. FILETIME *lpOrgFileTime
  1305. )
  1306. /*++
  1307. Routine Description:
  1308. Arguments:
  1309. Returns:
  1310. Notes:
  1311. --*/
  1312. {
  1313. #ifdef UNICODE
  1314. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1315. return (FALSE);
  1316. #else
  1317. return(CSCFindNextFileInternal(
  1318. hFind,
  1319. lpFind32,
  1320. lpdwStatus,
  1321. lpdwPinCount,
  1322. lpdwHintFlags,
  1323. lpOrgFileTime
  1324. ));
  1325. #endif
  1326. }
  1327. BOOL
  1328. WINAPI
  1329. CSCDeleteA(
  1330. LPCSTR lpszFileName
  1331. )
  1332. /*++
  1333. Routine Description:
  1334. Arguments:
  1335. Returns:
  1336. Notes:
  1337. --*/
  1338. {
  1339. #ifdef UNICODE
  1340. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1341. return (FALSE);
  1342. #else
  1343. return (CSCDeleteInternal(lpszFileName));
  1344. #endif
  1345. }
  1346. BOOL
  1347. WINAPI
  1348. CSCFillSparseFilesA(
  1349. IN LPCSTR lpszShareName,
  1350. IN BOOL fFullSync,
  1351. IN LPCSCPROCA lpfnFillProgress,
  1352. IN DWORD_PTR dwContext
  1353. )
  1354. /*++
  1355. Routine Description:
  1356. Arguments:
  1357. Returns:
  1358. Notes:
  1359. --*/
  1360. {
  1361. #ifdef UNICODE
  1362. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1363. return (FALSE);
  1364. #else
  1365. return (CSCFillSparseFilesInternal(
  1366. lpszShareName,
  1367. fFullSync,
  1368. lpfnFillProgress,
  1369. dwContext));
  1370. #endif
  1371. }
  1372. BOOL
  1373. WINAPI
  1374. CSCMergeShareA(
  1375. IN LPCSTR lpszShareName,
  1376. IN LPCSCPROCA lpfnMergeProgress,
  1377. IN DWORD_PTR dwContext
  1378. )
  1379. /*++
  1380. Routine Description:
  1381. Arguments:
  1382. Returns:
  1383. Notes:
  1384. --*/
  1385. {
  1386. #ifdef UNICODE
  1387. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1388. return (FALSE);
  1389. #else
  1390. return(CSCMergeShareInternal(
  1391. lpszShareName,
  1392. lpfnMergeProgress,
  1393. dwContext));
  1394. #endif
  1395. }
  1396. BOOL
  1397. WINAPI
  1398. CSCCopyReplicaA(
  1399. IN LPCSTR lpszFullPath,
  1400. OUT LPSTR *lplpszLocalName
  1401. )
  1402. /*++
  1403. Routine Description:
  1404. Arguments:
  1405. Returns:
  1406. Notes:
  1407. --*/
  1408. {
  1409. #ifdef UNICODE
  1410. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1411. return (FALSE);
  1412. #else
  1413. return(CSCCopyReplicaInternal(
  1414. lpszFullPath,
  1415. lplpszLocalName));
  1416. #endif
  1417. }
  1418. BOOL
  1419. WINAPI
  1420. CSCEnumForStatsA(
  1421. IN LPCSTR lpszShareName,
  1422. IN LPCSCPROCA lpfnEnumProgress,
  1423. IN DWORD_PTR dwContext
  1424. )
  1425. /*++
  1426. Routine Description:
  1427. Arguments:
  1428. Returns:
  1429. Notes:
  1430. --*/
  1431. {
  1432. #ifdef UNICODE
  1433. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1434. return (FALSE);
  1435. #else
  1436. return(CSCEnumForStatsInternal(
  1437. lpszShareName,
  1438. lpfnEnumProgress,
  1439. FALSE,
  1440. FALSE,
  1441. dwContext));
  1442. #endif
  1443. }
  1444. BOOL
  1445. WINAPI
  1446. CSCPinFileW(
  1447. IN LPCWSTR lpszFileName,
  1448. IN DWORD dwHintFlags,
  1449. IN LPDWORD lpdwStatus,
  1450. IN LPDWORD lpdwPinCount,
  1451. IN LPDWORD lpdwHintFlags
  1452. )
  1453. /*++
  1454. Routine Description:
  1455. Arguments:
  1456. Returns:
  1457. Notes:
  1458. --*/
  1459. {
  1460. #ifndef UNICODE
  1461. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1462. return (FALSE);
  1463. #else
  1464. return (CSCPinFileInternal(lpszFileName, dwHintFlags, lpdwStatus, lpdwPinCount, lpdwHintFlags));
  1465. #endif
  1466. }
  1467. BOOL
  1468. WINAPI
  1469. CSCUnpinFileW(
  1470. IN LPCWSTR lpszFileName,
  1471. IN DWORD dwHintFlags,
  1472. IN LPDWORD lpdwStatus,
  1473. IN LPDWORD lpdwPinCount,
  1474. IN LPDWORD lpdwHintFlags
  1475. )
  1476. /*++
  1477. Routine Description:
  1478. Arguments:
  1479. Returns:
  1480. Notes:
  1481. --*/
  1482. {
  1483. #ifndef UNICODE
  1484. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1485. return (FALSE);
  1486. #else
  1487. return (CSCUnpinFileInternal(lpszFileName, dwHintFlags, lpdwStatus, lpdwPinCount, lpdwHintFlags));
  1488. #endif
  1489. }
  1490. BOOL
  1491. WINAPI
  1492. CSCQueryFileStatusW(
  1493. LPCWSTR lpszFileName,
  1494. LPDWORD lpdwStatus,
  1495. LPDWORD lpdwPinCount,
  1496. LPDWORD lpdwHintFlags
  1497. )
  1498. /*++
  1499. Routine Description:
  1500. Arguments:
  1501. Returns:
  1502. Notes:
  1503. --*/
  1504. {
  1505. #ifndef UNICODE
  1506. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1507. return (FALSE);
  1508. #else
  1509. return (CSCQueryFileStatusInternal(
  1510. lpszFileName,
  1511. lpdwStatus,
  1512. lpdwPinCount,
  1513. lpdwHintFlags,
  1514. NULL,
  1515. NULL));
  1516. #endif
  1517. }
  1518. BOOL
  1519. WINAPI
  1520. CSCQueryFileStatusExW(
  1521. LPCWSTR lpszFileName,
  1522. LPDWORD lpdwStatus,
  1523. LPDWORD lpdwPinCount,
  1524. LPDWORD lpdwHintFlags,
  1525. LPDWORD lpdwUserPerms,
  1526. LPDWORD lpdwOtherPerms
  1527. )
  1528. /*++
  1529. Routine Description:
  1530. Arguments:
  1531. Returns:
  1532. Notes:
  1533. --*/
  1534. {
  1535. #ifndef UNICODE
  1536. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1537. return (FALSE);
  1538. #else
  1539. return (CSCQueryFileStatusInternal(
  1540. lpszFileName,
  1541. lpdwStatus,
  1542. lpdwPinCount,
  1543. lpdwHintFlags,
  1544. lpdwUserPerms,
  1545. lpdwOtherPerms));
  1546. #endif
  1547. }
  1548. BOOL
  1549. WINAPI
  1550. CSCQueryShareStatusW(
  1551. LPCWSTR lpszFileName,
  1552. LPDWORD lpdwStatus,
  1553. LPDWORD lpdwPinCount,
  1554. LPDWORD lpdwHintFlags,
  1555. LPDWORD lpdwUserPerms,
  1556. LPDWORD lpdwOtherPerms)
  1557. {
  1558. BOOL fStatus = FALSE;
  1559. BOOL fDfsStatus = FALSE;
  1560. DWORD dwDfsStatus;
  1561. WCHAR lpszOrgPath[MAX_PATH];
  1562. WCHAR lpszDfsPath[MAX_PATH];
  1563. PWCHAR wCp;
  1564. ULONG sCount;
  1565. #ifndef UNICODE
  1566. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1567. return (FALSE);
  1568. #else
  1569. // DbgPrint("CSCQueryShareStatusW(%ws)\n", lpszFileName);
  1570. //
  1571. // Save a copy of the original path passed in
  1572. //
  1573. wcscpy(lpszOrgPath, lpszFileName);
  1574. // Now truncate to just \\server\share
  1575. for (sCount = 0, wCp = lpszOrgPath; *wCp !=L'\0'; wCp++) {
  1576. if (*wCp == L'\\') {
  1577. if (++sCount == 4) {
  1578. *wCp = L'\0';
  1579. break;
  1580. }
  1581. }
  1582. }
  1583. // DbgPrint(" OrgPath=%ws\n", lpszOrgPath);
  1584. fStatus = CSCQueryFileStatusInternal(
  1585. lpszOrgPath,
  1586. lpdwStatus,
  1587. lpdwPinCount,
  1588. lpdwHintFlags,
  1589. lpdwUserPerms,
  1590. lpdwOtherPerms);
  1591. //
  1592. // If we found info, check if DFS, and (if so)
  1593. // adjust Status
  1594. //
  1595. if (fStatus == TRUE) {
  1596. DWORD Junk;
  1597. lpszDfsPath[0] = L'\0';
  1598. fDfsStatus = UncPathToDfsPath(
  1599. (PWCHAR)lpszFileName,
  1600. lpszDfsPath,
  1601. sizeof(lpszDfsPath));
  1602. if (fDfsStatus != TRUE)
  1603. goto AllDone;
  1604. // DbgPrint("DfsPath(1)=%ws\n", lpszDfsPath);
  1605. // turn into just \\server\share
  1606. for (sCount = 0, wCp = lpszDfsPath; *wCp !=L'\0'; wCp++) {
  1607. if (*wCp == L'\\') {
  1608. if (++sCount == 4) {
  1609. *wCp = L'\0';
  1610. break;
  1611. }
  1612. }
  1613. }
  1614. // DbgPrint("DfsPath(2)=%ws\n", lpszDfsPath);
  1615. fDfsStatus = CSCQueryFileStatusInternal(
  1616. lpszDfsPath,
  1617. &dwDfsStatus,
  1618. &Junk,
  1619. &Junk,
  1620. &Junk,
  1621. &Junk);
  1622. if (
  1623. fDfsStatus == TRUE
  1624. &&
  1625. (dwDfsStatus & FLAG_CSC_SHARE_STATUS_CACHING_MASK) == FLAG_CSC_SHARE_STATUS_NO_CACHING
  1626. ) {
  1627. *lpdwStatus &= ~FLAG_CSC_SHARE_STATUS_CACHING_MASK;
  1628. *lpdwStatus |= FLAG_CSC_SHARE_STATUS_NO_CACHING;
  1629. // DbgPrint("New Status=0x%x\n", dwDfsStatus);
  1630. }
  1631. }
  1632. AllDone:
  1633. return fStatus;
  1634. #endif
  1635. }
  1636. HANDLE
  1637. WINAPI
  1638. CSCFindFirstFileW(
  1639. LPCWSTR lpszFileName,
  1640. WIN32_FIND_DATAW *lpFind32,
  1641. LPDWORD lpdwStatus,
  1642. LPDWORD lpdwPinCount,
  1643. LPDWORD lpdwHintFlags,
  1644. FILETIME *lpOrgFileTime
  1645. )
  1646. /*++
  1647. Routine Description:
  1648. Arguments:
  1649. Returns:
  1650. Notes:
  1651. --*/
  1652. {
  1653. #ifndef UNICODE
  1654. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1655. return (INVALID_HANDLE_VALUE);
  1656. #else
  1657. return (CSCFindFirstFileInternal(
  1658. lpszFileName,
  1659. CSC_INVALID_PRINCIPAL_ID,
  1660. lpFind32,
  1661. lpdwStatus,
  1662. lpdwPinCount,
  1663. lpdwHintFlags,
  1664. lpOrgFileTime
  1665. ));
  1666. #endif
  1667. }
  1668. HANDLE
  1669. WINAPI
  1670. CSCFindFirstFileForSidW(
  1671. LPCWSTR lpszFileName,
  1672. PSID pSid,
  1673. WIN32_FIND_DATAW *lpFind32,
  1674. LPDWORD lpdwStatus,
  1675. LPDWORD lpdwPinCount,
  1676. LPDWORD lpdwHintFlags,
  1677. FILETIME *lpOrgFileTime
  1678. )
  1679. /*++
  1680. Routine Description:
  1681. Arguments:
  1682. Returns:
  1683. Notes:
  1684. --*/
  1685. {
  1686. ULONG ulPrincipalID;
  1687. #ifndef UNICODE
  1688. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1689. return (INVALID_HANDLE_VALUE);
  1690. #else
  1691. if (pSid)
  1692. {
  1693. if(!FindCreatePrincipalIDFromSID(INVALID_HANDLE_VALUE, pSid, GetLengthSid(pSid), &ulPrincipalID, FALSE))
  1694. {
  1695. return INVALID_HANDLE_VALUE;
  1696. }
  1697. }
  1698. else
  1699. {
  1700. ulPrincipalID = CSC_INVALID_PRINCIPAL_ID;
  1701. }
  1702. return (CSCFindFirstFileInternal(
  1703. lpszFileName,
  1704. ulPrincipalID,
  1705. lpFind32,
  1706. lpdwStatus,
  1707. lpdwPinCount,
  1708. lpdwHintFlags,
  1709. lpOrgFileTime
  1710. ));
  1711. #endif
  1712. }
  1713. BOOL
  1714. WINAPI
  1715. CSCFindNextFileW(
  1716. HANDLE hFind,
  1717. WIN32_FIND_DATAW *lpFind32,
  1718. LPDWORD lpdwStatus,
  1719. LPDWORD lpdwPinCount,
  1720. LPDWORD lpdwHintFlags,
  1721. FILETIME *lpOrgFileTime
  1722. )
  1723. /*++
  1724. Routine Description:
  1725. Arguments:
  1726. Returns:
  1727. Notes:
  1728. --*/
  1729. {
  1730. #ifndef UNICODE
  1731. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1732. return (FALSE);
  1733. #else
  1734. return(CSCFindNextFileInternal(
  1735. hFind,
  1736. lpFind32,
  1737. lpdwStatus,
  1738. lpdwPinCount,
  1739. lpdwHintFlags,
  1740. lpOrgFileTime
  1741. ));
  1742. #endif
  1743. }
  1744. BOOL
  1745. WINAPI
  1746. CSCDeleteW(
  1747. LPCWSTR lpszFileName
  1748. )
  1749. /*++
  1750. Routine Description:
  1751. Arguments:
  1752. Returns:
  1753. Notes:
  1754. --*/
  1755. {
  1756. #ifndef UNICODE
  1757. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1758. return (FALSE);
  1759. #else
  1760. return (CSCDeleteInternal(lpszFileName));
  1761. #endif
  1762. }
  1763. BOOL
  1764. WINAPI
  1765. CSCFillSparseFilesW(
  1766. IN LPCWSTR lpszShareName,
  1767. IN BOOL fFullSync,
  1768. IN LPCSCPROCW lpfnFillProgress,
  1769. IN DWORD_PTR dwContext
  1770. )
  1771. /*++
  1772. Routine Description:
  1773. Arguments:
  1774. Returns:
  1775. Notes:
  1776. --*/
  1777. {
  1778. #ifndef UNICODE
  1779. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1780. return (FALSE);
  1781. #else
  1782. return (CSCFillSparseFilesInternal(
  1783. lpszShareName,
  1784. fFullSync,
  1785. lpfnFillProgress,
  1786. dwContext));
  1787. #endif
  1788. }
  1789. BOOL
  1790. WINAPI
  1791. CSCMergeShareW(
  1792. IN LPCWSTR lpszShareName,
  1793. IN LPCSCPROCW lpfnMergeProgress,
  1794. IN DWORD_PTR dwContext
  1795. )
  1796. /*++
  1797. Routine Description:
  1798. Arguments:
  1799. Returns:
  1800. Notes:
  1801. --*/
  1802. {
  1803. #ifndef UNICODE
  1804. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1805. return (FALSE);
  1806. #else
  1807. return(CSCMergeShareInternal(
  1808. lpszShareName,
  1809. lpfnMergeProgress,
  1810. dwContext));
  1811. #endif
  1812. }
  1813. BOOL
  1814. WINAPI
  1815. CSCCopyReplicaW(
  1816. IN LPCWSTR lpszFullPath,
  1817. OUT LPWSTR *lplpszLocalName
  1818. )
  1819. /*++
  1820. Routine Description:
  1821. Arguments:
  1822. Returns:
  1823. Notes:
  1824. --*/
  1825. {
  1826. #ifndef UNICODE
  1827. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1828. return (FALSE);
  1829. #else
  1830. return(CSCCopyReplicaInternal(
  1831. lpszFullPath,
  1832. lplpszLocalName));
  1833. #endif
  1834. }
  1835. BOOL
  1836. WINAPI
  1837. CSCEnumForStatsW(
  1838. IN LPCWSTR lpszShareName,
  1839. IN LPCSCPROCW lpfnEnumProgress,
  1840. IN DWORD_PTR dwContext
  1841. )
  1842. /*++
  1843. Routine Description:
  1844. Arguments:
  1845. Returns:
  1846. Notes:
  1847. --*/
  1848. {
  1849. #ifndef UNICODE
  1850. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1851. return (FALSE);
  1852. #else
  1853. return(CSCEnumForStatsInternal(
  1854. lpszShareName,
  1855. lpfnEnumProgress,
  1856. FALSE,
  1857. FALSE,
  1858. dwContext));
  1859. #endif
  1860. }
  1861. BOOL
  1862. WINAPI
  1863. CSCEnumForStatsExA(
  1864. IN LPCSTR lpszShareName,
  1865. IN LPCSCPROCA lpfnEnumProgress,
  1866. IN DWORD_PTR dwContext
  1867. )
  1868. /*++
  1869. Routine Description:
  1870. Arguments:
  1871. Returns:
  1872. Notes:
  1873. --*/
  1874. {
  1875. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1876. return (FALSE);
  1877. }
  1878. BOOL
  1879. WINAPI
  1880. CSCEnumForStatsExW(
  1881. IN LPCWSTR lpszShareName,
  1882. IN LPCSCPROCW lpfnEnumProgress,
  1883. IN DWORD_PTR dwContext
  1884. )
  1885. /*++
  1886. Routine Description:
  1887. Arguments:
  1888. Returns:
  1889. Notes:
  1890. --*/
  1891. {
  1892. #ifndef UNICODE
  1893. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1894. return (FALSE);
  1895. #else
  1896. return(CSCEnumForStatsInternal(
  1897. lpszShareName,
  1898. lpfnEnumProgress,
  1899. TRUE,
  1900. FALSE,
  1901. dwContext));
  1902. #endif
  1903. }
  1904. BOOL
  1905. WINAPI
  1906. CSCFreeSpace(
  1907. DWORD nFileSizeHigh,
  1908. DWORD nFileSizeLow
  1909. )
  1910. /*++
  1911. Routine Description:
  1912. Arguments:
  1913. Returns:
  1914. Notes:
  1915. --*/
  1916. {
  1917. SHADOWSTORE sSTLast, sST;
  1918. BOOL fRet = FALSE;
  1919. if(!GetSpaceStats(INVALID_HANDLE_VALUE, &sSTLast))
  1920. {
  1921. return FALSE;
  1922. }
  1923. do
  1924. {
  1925. if (!FreeShadowSpace(INVALID_HANDLE_VALUE, nFileSizeHigh, nFileSizeLow, FALSE))
  1926. {
  1927. break;
  1928. }
  1929. if(!GetSpaceStats(INVALID_HANDLE_VALUE, &sST))
  1930. {
  1931. break;
  1932. }
  1933. // check if we are making any progress over successive
  1934. // free space calls. If the current space used is greater than
  1935. // after we last called, just quit.
  1936. if (sST.sCur.ulSize >= sSTLast.sCur.ulSize)
  1937. {
  1938. fRet = TRUE;
  1939. break;
  1940. }
  1941. sSTLast = sST;
  1942. }
  1943. while (TRUE);
  1944. return fRet;
  1945. }
  1946. BOOL
  1947. WINAPI
  1948. CSCIsServerOfflineW(
  1949. LPCWSTR lptzServerName,
  1950. BOOL *lpfOffline
  1951. )
  1952. /*++
  1953. Routine Description:
  1954. Arguments:
  1955. Returns:
  1956. Notes:
  1957. --*/
  1958. {
  1959. return(IsServerOfflineW(INVALID_HANDLE_VALUE, lptzServerName, lpfOffline));
  1960. }
  1961. BOOL
  1962. WINAPI
  1963. CSCIsServerOfflineA(
  1964. LPCSTR lptzServerName,
  1965. BOOL *lpfOffline
  1966. )
  1967. /*++
  1968. Routine Description:
  1969. Arguments:
  1970. Returns:
  1971. Notes:
  1972. --*/
  1973. {
  1974. return(IsServerOfflineA(INVALID_HANDLE_VALUE, lptzServerName, lpfOffline));
  1975. }
  1976. BOOL
  1977. WINAPI
  1978. CSCTransitionServerOnlineW(
  1979. IN LPCWSTR lpszShareName
  1980. )
  1981. /*++
  1982. Routine Description:
  1983. This routine transitions the server for the given share to online.
  1984. Arguments:
  1985. lpszShareName
  1986. Returns:
  1987. Notes:
  1988. --*/
  1989. {
  1990. WIN32_FIND_DATA sFind32;
  1991. SHADOWINFO sSI;
  1992. BOOL fTransitionedToOnline = FALSE, fDone=FALSE;
  1993. _TCHAR tchBuff[MAX_SERVER_SHARE_NAME_FOR_CSC], tzDrive[4];
  1994. DWORD i;
  1995. if (lstrlen(lpszShareName) >= MAX_SERVER_SHARE_NAME_FOR_CSC)
  1996. {
  1997. SetLastError(ERROR_INVALID_PARAMETER);
  1998. return FALSE;
  1999. }
  2000. lstrcpy(tchBuff, lpszShareName);
  2001. if (!LpBreakPath(tchBuff, TRUE, &fDone) && !fDone)
  2002. {
  2003. SetLastError(ERROR_INVALID_PARAMETER);
  2004. return FALSE;
  2005. }
  2006. tzDrive[0] = 0;
  2007. if(FindCreateShadowFromPath(tchBuff, FALSE, &sFind32, &sSI, NULL))
  2008. {
  2009. LPCONNECTINFO lpHead = NULL;
  2010. BOOL fServerIsOffline = FALSE;
  2011. fServerIsOffline = ((sSI.uStatus & SHARE_DISCONNECTED_OP) != 0);
  2012. if(FGetConnectionListEx(&lpHead, tchBuff, TRUE, fServerIsOffline, NULL))
  2013. {
  2014. // take an extra reference, just in case there are some credentials on the server entry
  2015. // with the redir
  2016. // if it fails, don't stop going online
  2017. // the worst that could happen is that the user might get an extra popup
  2018. // for the explicit credential case
  2019. DWORD dwError;
  2020. dwError = DWConnectNet(tchBuff, tzDrive, NULL, NULL, NULL, 0, NULL);
  2021. if ((dwError != WN_SUCCESS) && (dwError != WN_CONNECTED_OTHER_PASSWORD_DEFAULT))
  2022. {
  2023. tzDrive[0] = 0;
  2024. }
  2025. DisconnectList(&lpHead, NULL, 0);
  2026. }
  2027. fTransitionedToOnline = TransitionShareToOnline(INVALID_HANDLE_VALUE, sSI.hShare);
  2028. for (i=2;i<MAX_SERVER_SHARE_NAME_FOR_CSC;++i)
  2029. {
  2030. if (tchBuff[i] == '\\')
  2031. {
  2032. break;
  2033. }
  2034. }
  2035. Assert(i< MAX_SERVER_SHARE_NAME_FOR_CSC);
  2036. // going online
  2037. ReportTransitionToDfs(tchBuff, FALSE, i*sizeof(_TCHAR));
  2038. if (lpHead)
  2039. {
  2040. ReconnectList(&lpHead, NULL);
  2041. ClearConnectionList(&lpHead);
  2042. }
  2043. // if there was an extra reference,
  2044. // remove it
  2045. if (tzDrive[0])
  2046. {
  2047. DWDisconnectDriveMappedNet(tzDrive, TRUE);
  2048. }
  2049. }
  2050. return(fTransitionedToOnline);
  2051. }
  2052. BOOL
  2053. WINAPI
  2054. CSCTransitionServerOnlineA(
  2055. IN LPCSTR lpszShareName
  2056. )
  2057. /*++
  2058. Routine Description:
  2059. Arguments:
  2060. Returns:
  2061. Notes:
  2062. --*/
  2063. {
  2064. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  2065. return (FALSE);
  2066. }
  2067. BOOL
  2068. WINAPI
  2069. CSCCheckShareOnlineExW(
  2070. IN LPCWSTR lpszShareName,
  2071. LPDWORD lpdwSpeed
  2072. )
  2073. /*++
  2074. Routine Description:
  2075. This routine checks whether a given share is available online.
  2076. Arguments:
  2077. lpszShareName
  2078. Returns:
  2079. Notes:
  2080. --*/
  2081. {
  2082. _TCHAR tchBuff[MAX_SERVER_SHARE_NAME_FOR_CSC], tzDrive[4];
  2083. BOOL fIsOnline = FALSE, fDone;
  2084. DWORD dwError;
  2085. if (lstrlen(lpszShareName) >= MAX_SERVER_SHARE_NAME_FOR_CSC)
  2086. {
  2087. SetLastError(ERROR_INVALID_PARAMETER);
  2088. return FALSE;
  2089. }
  2090. lstrcpy(tchBuff, lpszShareName);
  2091. if (!LpBreakPath(tchBuff, TRUE, &fDone) && !fDone)
  2092. {
  2093. SetLastError(ERROR_INVALID_PARAMETER);
  2094. return FALSE;
  2095. }
  2096. dwError = DWConnectNet(tchBuff, tzDrive, NULL, NULL, NULL, 0, NULL);
  2097. if ((dwError == WN_SUCCESS) || (dwError == WN_CONNECTED_OTHER_PASSWORD_DEFAULT))
  2098. {
  2099. fIsOnline = TRUE;
  2100. if (lpdwSpeed)
  2101. {
  2102. GetConnectionInfoForDriveBasedName(tzDrive, lpdwSpeed);
  2103. }
  2104. DWDisconnectDriveMappedNet(tzDrive, TRUE);
  2105. }
  2106. else
  2107. {
  2108. SetLastError(dwError);
  2109. }
  2110. return(fIsOnline);
  2111. }
  2112. BOOL
  2113. WINAPI
  2114. CSCCheckShareOnlineW(
  2115. IN LPCWSTR lpszShareName
  2116. )
  2117. /*++
  2118. Routine Description:
  2119. This routine checks whether a given share is available online.
  2120. Arguments:
  2121. lpszShareName
  2122. Returns:
  2123. Notes:
  2124. --*/
  2125. {
  2126. return (CSCCheckShareOnlineExW(lpszShareName, NULL));
  2127. }
  2128. BOOL
  2129. WINAPI
  2130. CSCCheckShareOnlineA(
  2131. IN LPCSTR lpszShareName
  2132. )
  2133. /*++
  2134. Routine Description:
  2135. Arguments:
  2136. Returns:
  2137. Notes:
  2138. --*/
  2139. {
  2140. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  2141. return (FALSE);
  2142. }
  2143. BOOL
  2144. WINAPI
  2145. CSCDoLocalRenameW(
  2146. IN LPCWSTR lpszSource,
  2147. IN LPCWSTR lpszDestination,
  2148. IN BOOL fReplaceFileIfExists
  2149. )
  2150. {
  2151. return CSCDoLocalRenameExW(lpszSource, lpszDestination, NULL, FALSE, fReplaceFileIfExists);
  2152. }
  2153. BOOL
  2154. WINAPI
  2155. CSCDoLocalRenameExW(
  2156. IN LPCWSTR lpszSource,
  2157. IN LPCWSTR lpszDestination,
  2158. IN WIN32_FIND_DATAW *lpFind32,
  2159. IN BOOL fMarkAsLocal,
  2160. IN BOOL fReplaceFileIfExists
  2161. )
  2162. /*++
  2163. Routine Description:
  2164. This routine does a rename in the datbase. The rename operation can be across shares
  2165. Arguments:
  2166. lpszSource Fully qualified source name (must be UNC)
  2167. lpszDestination Fully qualified destination directory name (must be UNC)
  2168. lpFind32 New name in the destination directory, given the long name
  2169. the shortnmae is locally generated. For this reason, when
  2170. a new name is given, fMarkAsLocal is forced TRUE.
  2171. fMarkAsLocal Mark the newly created entry as locally created (except see lpFind32)
  2172. fReplaceFileIfExists replace destination file with the source if it exists
  2173. Returns:
  2174. TRUE if successfull, FALSE otherwise. If the API fails, GetLastError returns the specific
  2175. errorcode.
  2176. Notes:
  2177. --*/
  2178. {
  2179. DWORD dwError = NO_ERROR;
  2180. WIN32_FIND_DATA sFind32;
  2181. BOOL fDone=FALSE, fRet = FALSE, fBeginInodeTransaction = FALSE, fSourceIsFile=FALSE;
  2182. SHADOWINFO sSI;
  2183. HSHADOW hDirFrom, hShadowFrom, hDirTo, hShadowTo=0;
  2184. HSHARE hShareFrom, hShareTo;
  2185. HANDLE hShadowDB;
  2186. DWORD lenSrc=0, lenDst=0;
  2187. ReintKdPrint(API, ("DoLocalRenameEx %ls %ls %x %x %x\r\n", lpszSource, lpszDestination, lpFind32, fMarkAsLocal, fReplaceFileIfExists));
  2188. try
  2189. {
  2190. if ((lenSrc = lstrlen(lpszSource)) >= MAX_PATH)
  2191. {
  2192. SetLastError(ERROR_INVALID_PARAMETER);
  2193. return FALSE;
  2194. }
  2195. lstrcpy(sFind32.cFileName, lpszSource);
  2196. if (!LpBreakPath(sFind32.cFileName, TRUE, &fDone) && fDone)
  2197. {
  2198. SetLastError(ERROR_INVALID_PARAMETER);
  2199. return FALSE;
  2200. }
  2201. }
  2202. except(EXCEPTION_EXECUTE_HANDLER)
  2203. {
  2204. SetLastError(ERROR_INVALID_PARAMETER);
  2205. return FALSE;
  2206. }
  2207. try
  2208. {
  2209. if ((lenDst = lstrlen(lpszDestination)) >= MAX_PATH)
  2210. {
  2211. SetLastError(ERROR_INVALID_PARAMETER);
  2212. return FALSE;
  2213. }
  2214. }
  2215. except(EXCEPTION_EXECUTE_HANDLER)
  2216. {
  2217. SetLastError(ERROR_INVALID_PARAMETER);
  2218. return FALSE;
  2219. }
  2220. // if source is not greater than the destination
  2221. // verify that we are not renaming the parent under it's own child
  2222. if (lenSrc <= lenDst)
  2223. {
  2224. lstrcpy(sFind32.cFileName, lpszDestination);
  2225. sFind32.cFileName[lenSrc] = 0;
  2226. // make a case insensitive comparison
  2227. if(!lstrcmpi(lpszSource, sFind32.cFileName))
  2228. {
  2229. SetLastError(ERROR_INVALID_PARAMETER);
  2230. return FALSE;
  2231. }
  2232. }
  2233. if ((hShadowDB = OpenShadowDatabaseIO()) ==INVALID_HANDLE_VALUE)
  2234. {
  2235. ReintKdPrint(BADERRORS, ("failed to open database\r\n"));
  2236. return FALSE;
  2237. }
  2238. if(BeginInodeTransactionHSHADOW())
  2239. {
  2240. fBeginInodeTransaction = TRUE;
  2241. if(!FindCreateShadowFromPath(lpszSource, FALSE, &sFind32, &sSI, NULL))
  2242. {
  2243. goto bailout;
  2244. }
  2245. ReintKdPrint(API, ("Source Share = %x Inode %x %x\r\n", sSI.hShare, sSI.hDir, sSI.hShadow));
  2246. hDirFrom = sSI.hDir;
  2247. hShadowFrom = sSI.hShadow;
  2248. hShareFrom = sSI.hShare;
  2249. fSourceIsFile = ((sFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==0);
  2250. if(!FindCreateShadowFromPath(lpszDestination, TRUE, &sFind32, &sSI, NULL))
  2251. {
  2252. goto bailout;
  2253. }
  2254. ReintKdPrint(API, ("Destination Share = %x Inode %x %x\r\n", sSI.hShare, sSI.hDir, sSI.hShadow));
  2255. hShareTo = sSI.hShare;
  2256. hDirTo = sSI.hShadow;
  2257. // if we are creating a new entry in the database, we say it was created
  2258. // offline
  2259. if (lpFind32)
  2260. {
  2261. fMarkAsLocal = TRUE;
  2262. fReplaceFileIfExists = FALSE;
  2263. }
  2264. if (((hShareFrom == hShareTo) && !fReplaceFileIfExists) ||fSourceIsFile)
  2265. {
  2266. // do the rename only if the source directory is not the same as the destination directory.
  2267. // or the destination name is different, otherwise there is nothing to do
  2268. if ((hDirFrom != sSI.hShadow)||(lpFind32))
  2269. {
  2270. if (RenameShadow(hShadowDB, hDirFrom, hShadowFrom, hDirTo, lpFind32, fReplaceFileIfExists, &hShadowTo))
  2271. {
  2272. //
  2273. fRet = SetShareStatus(hShadowDB, hShareTo, SHARE_REINT, SHADOW_FLAGS_OR);
  2274. if (fMarkAsLocal)
  2275. {
  2276. Assert(hShadowTo);
  2277. if (fSourceIsFile)
  2278. {
  2279. fRet = SetShadowInfo(hShadowDB, hDirTo, hShadowTo, NULL, SHADOW_LOCALLY_CREATED, SHADOW_FLAGS_ASSIGN);
  2280. }
  2281. else
  2282. {
  2283. SET_SUBTREE_STATUS sSSS;
  2284. memset(&sSSS, 0, sizeof(sSSS));
  2285. sSSS.uStatus = SHADOW_LOCALLY_CREATED;
  2286. sSSS.uOp = SHADOW_FLAGS_ASSIGN;
  2287. fRet = (TraverseOneDirectory(hShadowDB, NULL, hDirTo, hShadowTo, (LPTSTR)lpszSource, SetSubtreeStatus, &sSSS)!=TOD_ABORT);
  2288. }
  2289. }
  2290. if (!fRet)
  2291. {
  2292. dwError = GetLastError();
  2293. }
  2294. }
  2295. else
  2296. {
  2297. dwError = GetLastError();
  2298. }
  2299. }
  2300. else
  2301. {
  2302. fRet = TRUE;
  2303. }
  2304. }
  2305. else
  2306. {
  2307. MOVE_SUBTREE sMST;
  2308. memset(&sMST, 0, sizeof(sMST));
  2309. sMST.lptzSource = lpszSource;
  2310. sMST.lptzDestination = lpszDestination;
  2311. sMST.lpTos = &sMST.sTos;
  2312. sMST.sTos.hDir = hDirTo;
  2313. sMST.hShareTo = hShareTo;
  2314. if (fReplaceFileIfExists)
  2315. {
  2316. sMST.dwFlags |= MST_REPLACE_IF_EXISTS;
  2317. }
  2318. TraverseOneDirectory(hShadowDB, NULL, hDirFrom, hShadowFrom, (LPTSTR)lpszSource, MoveSubtree, &sMST);
  2319. fRet = (sMST.cntFail == 0);
  2320. Assert(sMST.lpTos == &sMST.sTos);
  2321. Assert(sMST.sTos.lpNext == NULL);
  2322. }
  2323. }
  2324. bailout:
  2325. if (fBeginInodeTransaction)
  2326. {
  2327. EndInodeTransactionHSHADOW();
  2328. }
  2329. if (!fRet)
  2330. {
  2331. SetLastError(dwError);
  2332. }
  2333. CloseShadowDatabaseIO(hShadowDB);
  2334. return fRet;
  2335. }
  2336. BOOL
  2337. CreateDirectoryAndSetHints(
  2338. HANDLE hShadowDB,
  2339. LPTSTR lptzFullPath,
  2340. DWORD dwCallbackReason,
  2341. WIN32_FIND_DATA *lpFind32,
  2342. SHADOWINFO *lpSI,
  2343. LPMOVE_SUBTREE lpMst
  2344. )
  2345. /*++
  2346. Routine Description:
  2347. This routine creates a copy of a source directory under a destination directory
  2348. Arguments:
  2349. hShadowDB Handle to issue ioctls to the redir
  2350. lptzFullPath fully qualified path to the item
  2351. dwCallbackReason TOD_CALLBACK_REASON_XXX (BEGIN, NEXT_ITEM or END)
  2352. lpFind32 local win32info
  2353. lpSI other info such as priority, pincount etc.
  2354. lpMst MOVE_SUBTREE structure which contains the rlevant info about this move
  2355. Returns:
  2356. TRUE if successfull, FALSE otherwise. If the API fails, GetLastError returns the specific
  2357. errorcode.
  2358. Notes:
  2359. --*/
  2360. {
  2361. BOOL fRet = FALSE;
  2362. lpMst->sFind32 = *lpFind32;
  2363. if(GetShadowEx(hShadowDB, lpMst->lpTos->hDir, &lpMst->sFind32, &lpMst->sSI))
  2364. {
  2365. // if it doesn't exist, create it and set it's hints to those found on the source
  2366. if (!lpMst->sSI.hShadow)
  2367. {
  2368. if (CreateShadow(hShadowDB, lpMst->lpTos->hDir, &lpMst->sFind32, lpSI->uStatus, &lpMst->sSI.hShadow))
  2369. {
  2370. lpMst->sSI.ulHintPri = lpSI->ulHintPri;
  2371. lpMst->sSI.ulHintFlags = lpSI->ulHintFlags;
  2372. if(AddHintFromInode(hShadowDB, lpMst->lpTos->hDir, lpMst->sSI.hShadow, &(lpMst->sSI.ulHintPri), &(lpMst->sSI.ulHintFlags)) != 0)
  2373. {
  2374. fRet = TRUE;
  2375. }
  2376. }
  2377. }
  2378. else
  2379. {
  2380. fRet = TRUE;
  2381. }
  2382. }
  2383. return fRet;
  2384. }
  2385. BOOL
  2386. WINAPI
  2387. CSCDoLocalRenameA(
  2388. IN LPCSTR lpszSource,
  2389. IN LPCSTR lpszDestination,
  2390. IN BOOL fReplcaeFileIfExists
  2391. )
  2392. /*++
  2393. Routine Description:
  2394. This routine does a rename in the datbase. The rename operation can be across shares
  2395. Arguments:
  2396. lpszSource Fully qualified source name (must be UNC)
  2397. lpszDestination Fully qualified destination name (must be UNC)
  2398. Returns:
  2399. TRUE if successfull, FALSE otherwise. If the API fails, GetLastError returns the specific
  2400. errorcode.
  2401. Notes:
  2402. --*/
  2403. {
  2404. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  2405. return (FALSE);
  2406. }
  2407. BOOL
  2408. WINAPI
  2409. CSCDoEnableDisable(
  2410. BOOL fEnable
  2411. )
  2412. /*++
  2413. Routine Description:
  2414. This routine enables/disables CSC
  2415. Arguments:
  2416. fEnable enable CSC if TRUE, else disable CSC
  2417. Returns:
  2418. TRUE if successfull, FALSE otherwise. If the API fails, GetLastError returns the specific
  2419. errorcode.
  2420. Notes:
  2421. --*/
  2422. {
  2423. BOOL fRet = FALSE, fReformat = FALSE;
  2424. char szDBDir[MAX_PATH+1];
  2425. DWORD dwDBCapacity, dwClusterSize;
  2426. if (IsPersonal() == TRUE) {
  2427. SetLastError(ERROR_INVALID_OPERATION);
  2428. return FALSE;
  2429. }
  2430. if (fEnable)
  2431. {
  2432. if (InitValues(szDBDir, sizeof(szDBDir), &dwDBCapacity, &dwClusterSize))
  2433. {
  2434. fReformat = QueryFormatDatabase();
  2435. fRet = EnableShadowingForUser(INVALID_HANDLE_VALUE, szDBDir, NULL, 0, dwDBCapacity, dwClusterSize, fReformat);
  2436. }
  2437. }
  2438. else
  2439. {
  2440. fRet = DisableShadowingForUser(INVALID_HANDLE_VALUE);
  2441. }
  2442. return fRet;
  2443. }
  2444. int
  2445. MoveSubtree(
  2446. HANDLE hShadowDB,
  2447. LPSECURITYINFO pShareSecurityInfo,
  2448. LPTSTR lptzFullPath,
  2449. DWORD dwCallbackReason,
  2450. WIN32_FIND_DATA *lpFind32,
  2451. SHADOWINFO *lpSI,
  2452. LPMOVE_SUBTREE lpMst
  2453. )
  2454. /*++
  2455. Routine Description:
  2456. This is a callback routine to TraverseOneDirectory. It moves the subtree from one place
  2457. in the hierarchy to another. It would be necessary to call this routine only when
  2458. the subtree is being moved from one share to another.
  2459. Arguments:
  2460. hShadowDB Handle to issue ioctls to the redir
  2461. lptzFullPath fully qualified path to the item
  2462. dwCallbackReason TOD_CALLBACK_REASON_XXX (BEGIN, NEXT_ITEM or END)
  2463. lpFind32 local win32info
  2464. lpSI other info such as priority, pincount etc.
  2465. lpMst MOVE_SUBTREE structure which contains the rlevant info about this move
  2466. Returns:
  2467. return code, whether continue, cancel etc.
  2468. Notes:
  2469. As TravesreOneDirectory descends the source subtree, this routine creates directories in the
  2470. corresponding location in the destination subtree. It then moves the files from one subtree
  2471. to another. At the end of the enumeration of any directory, it tries to delete the source
  2472. directory. The delete succeeds only if there are no more descedents left to the source
  2473. directory
  2474. --*/
  2475. {
  2476. BOOL fRet = FALSE;
  2477. LPMST_LIST lpT;
  2478. ReintKdPrint(API, ("MoveSubTree %ls\r\n", lptzFullPath));
  2479. switch (dwCallbackReason)
  2480. {
  2481. case TOD_CALLBACK_REASON_BEGIN:
  2482. {
  2483. ReintKdPrint(API, ("MST Begin source Inode %x %x\r\n", lpSI->hDir, lpSI->hShadow));
  2484. // Get the source directory info
  2485. if (GetShadowInfoEx(hShadowDB, lpSI->hDir, lpSI->hShadow, lpFind32, lpSI))
  2486. {
  2487. fRet = CreateDirectoryAndSetHints(hShadowDB, lptzFullPath, dwCallbackReason, lpFind32, lpSI, lpMst);
  2488. }
  2489. // if all is well, then make this directory the parent directory for
  2490. // all subsequent creates and renames
  2491. if (fRet)
  2492. {
  2493. lpT = (LPMST_LIST)LocalAlloc(LPTR, sizeof(MST_LIST));
  2494. if (!lpT)
  2495. {
  2496. return TOD_ABORT;
  2497. }
  2498. lpT->hDir = lpMst->sSI.hShadow;
  2499. lpT->lpNext = lpMst->lpTos;
  2500. lpMst->lpTos = lpT;
  2501. // mark the destination share dirty, if necessary
  2502. if (lpSI->uStatus & SHADOW_MODFLAGS)
  2503. {
  2504. if (!(lpMst->dwFlags & MST_SHARE_MARKED_DIRTY))
  2505. {
  2506. ReintKdPrint(API, ("Setting Share %x dirty \n", lpMst->hShareTo));
  2507. if(SetShareStatus(hShadowDB, lpMst->hShareTo, SHARE_REINT, SHADOW_FLAGS_OR))
  2508. {
  2509. lpMst->dwFlags |= MST_SHARE_MARKED_DIRTY;
  2510. }
  2511. }
  2512. }
  2513. }
  2514. else
  2515. {
  2516. lpMst->cntFail++;
  2517. }
  2518. }
  2519. break;
  2520. case TOD_CALLBACK_REASON_NEXT_ITEM:
  2521. // if the source is a file, then move it
  2522. ReintKdPrint(API, ("MST next source Inode %x %x\r\n", lpSI->hDir, lpSI->hShadow));
  2523. if(!(lpFind32->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  2524. {
  2525. ReintKdPrint(API, ("MST rename file SrcInode %x %x to destdir %x\r\n", lpSI->hDir, lpSI->hShadow, lpMst->lpTos->hDir));
  2526. if (RenameShadow(hShadowDB, lpSI->hDir, lpSI->hShadow, lpMst->lpTos->hDir, NULL,
  2527. ((lpMst->dwFlags & MST_REPLACE_IF_EXISTS)!=0), NULL))
  2528. {
  2529. fRet = TRUE;
  2530. }
  2531. }
  2532. else
  2533. {
  2534. if(CreateDirectoryAndSetHints(hShadowDB, lptzFullPath, dwCallbackReason, lpFind32, lpSI, lpMst))
  2535. {
  2536. fRet = TRUE;
  2537. }
  2538. }
  2539. if (!fRet)
  2540. {
  2541. lpMst->cntFail++;
  2542. }
  2543. // mark the destination share dirty, if necessary
  2544. if (lpSI->uStatus & SHADOW_MODFLAGS)
  2545. {
  2546. if (!(lpMst->dwFlags & MST_SHARE_MARKED_DIRTY))
  2547. {
  2548. if(SetShareStatus(hShadowDB, lpMst->hShareTo, SHARE_REINT, SHADOW_FLAGS_OR))
  2549. {
  2550. lpMst->dwFlags |= MST_SHARE_MARKED_DIRTY;
  2551. }
  2552. }
  2553. }
  2554. break;
  2555. case TOD_CALLBACK_REASON_END:
  2556. Assert(lpMst->lpTos);
  2557. lpT = lpMst->lpTos;
  2558. lpMst->lpTos = lpMst->lpTos->lpNext;
  2559. LocalFree(lpT);
  2560. fRet = TRUE;
  2561. ReintKdPrint(API, ("MST End Delete Inode %x %x \r\n", lpSI->hDir, lpSI->hShadow));
  2562. DeleteShadow(hShadowDB, lpSI->hDir, lpSI->hShadow);
  2563. break;
  2564. }
  2565. return (fRet?TOD_CONTINUE:TOD_ABORT);
  2566. }
  2567. int
  2568. SetSubtreeStatus(
  2569. HANDLE hShadowDB,
  2570. LPSECURITYINFO pShareSecurityInfo,
  2571. LPTSTR lptzFullPath,
  2572. DWORD dwCallbackReason,
  2573. WIN32_FIND_DATA *lpFind32,
  2574. SHADOWINFO *lpSI,
  2575. LPSET_SUBTREE_STATUS lpSss
  2576. )
  2577. /*++
  2578. Routine Description:
  2579. This is a callback routine to TraverseOneDirectory. It moves the subtree from one place
  2580. in the hierarchy to another. It would be necessary to call this routine only when
  2581. the subtree is being moved from one share to another.
  2582. Arguments:
  2583. hShadowDB Handle to issue ioctls to the redir
  2584. lptzFullPath fully qualified path to the item
  2585. dwCallbackReason TOD_CALLBACK_REASON_XXX (BEGIN, NEXT_ITEM or END)
  2586. lpFind32 local win32info
  2587. lpSI other info such as priority, pincount etc.
  2588. lpSss SET_SUBTREE_STATE structure which contains the relevant info about this state setting
  2589. Returns:
  2590. return code, whether continue, cancel etc.
  2591. Notes:
  2592. As TravesreOneDirectory descends the source subtree, this routine sets the required bits
  2593. --*/
  2594. {
  2595. ReintKdPrint(API, ("SetSubTreeState %ls\r\n", lptzFullPath));
  2596. if(SetShadowInfo(hShadowDB, lpSI->hDir, lpSI->hShadow, NULL, lpSss->uStatus, lpSss->uOp) == TRUE)
  2597. {
  2598. return TOD_CONTINUE;
  2599. }
  2600. else
  2601. {
  2602. return TOD_ABORT;
  2603. }
  2604. }
  2605. BOOL
  2606. WINAPI
  2607. CSCBeginSynchronizationW(
  2608. IN LPCTSTR lpszShareName,
  2609. LPDWORD lpdwSpeed,
  2610. LPDWORD lpdwContext
  2611. )
  2612. /*++
  2613. Routine Description:
  2614. Arguments:
  2615. Returns:
  2616. Notes:
  2617. --*/
  2618. {
  2619. _TCHAR tchBuff[MAX_SERVER_SHARE_NAME_FOR_CSC], tzDrive[4];
  2620. BOOL fIsOnline = FALSE, fDone, fExplicitCredentials=FALSE, fIsDfs;
  2621. DWORD dwError;
  2622. if (lstrlen(lpszShareName) >= MAX_SERVER_SHARE_NAME_FOR_CSC)
  2623. {
  2624. SetLastError(ERROR_INVALID_PARAMETER);
  2625. return FALSE;
  2626. }
  2627. lstrcpy(tchBuff, lpszShareName);
  2628. if (!LpBreakPath(tchBuff, TRUE, &fDone) && !fDone)
  2629. {
  2630. SetLastError(ERROR_INVALID_PARAMETER);
  2631. return FALSE;
  2632. }
  2633. ReintKdPrint(API, (" CSCBeginSynchronization %ls\r\n", tchBuff));
  2634. dwError = DWConnectNet(tchBuff, tzDrive, NULL, NULL, NULL, CONNECT_INTERACTIVE, NULL);
  2635. if ((dwError == WN_SUCCESS)||(dwError==WN_CONNECTED_OTHER_PASSWORD)||(dwError==WN_CONNECTED_OTHER_PASSWORD_DEFAULT))
  2636. {
  2637. fIsOnline = TRUE;
  2638. if (lpdwSpeed)
  2639. {
  2640. GetConnectionInfoForDriveBasedName(tzDrive, lpdwSpeed);
  2641. }
  2642. if (dwError==WN_CONNECTED_OTHER_PASSWORD || dwError==WN_CONNECTED_OTHER_PASSWORD_DEFAULT)
  2643. {
  2644. ReintKdPrint(API, (" CSCBeginSynchronization: Explicit Credentials\r\n"));
  2645. fExplicitCredentials = TRUE;
  2646. dwError = DoNetUseAddForAgent(tchBuff, NULL, NULL, NULL, NULL, 0, &fIsDfs);
  2647. if (dwError != WN_SUCCESS && dwError!=WN_CONNECTED_OTHER_PASSWORD_DEFAULT)
  2648. {
  2649. fIsOnline = FALSE;
  2650. ReintKdPrint(API, (" CSCBeginSynchronization: Failed extra reference %d\r\n", dwError));
  2651. }
  2652. }
  2653. DWDisconnectDriveMappedNet(tzDrive, TRUE);
  2654. }
  2655. if (!fIsOnline)
  2656. {
  2657. ReintKdPrint(ALWAYS, (" CSCBeginSynchronization: Failed %d\r\n", dwError));
  2658. SetLastError(dwError);
  2659. }
  2660. else
  2661. {
  2662. *lpdwContext = fExplicitCredentials;
  2663. }
  2664. return(fIsOnline);
  2665. }
  2666. BOOL
  2667. WINAPI
  2668. CSCEndSynchronizationW(
  2669. IN LPCTSTR lpszShareName,
  2670. DWORD dwContext
  2671. )
  2672. /*++
  2673. Routine Description:
  2674. Arguments:
  2675. Returns:
  2676. Notes:
  2677. --*/
  2678. {
  2679. _TCHAR tchBuff[MAX_SERVER_SHARE_NAME_FOR_CSC], tzDrive[4];
  2680. BOOL fIsOnline = FALSE, fDone, fExplicitCredentials=FALSE;
  2681. DWORD dwError;
  2682. if (lstrlen(lpszShareName) >= MAX_SERVER_SHARE_NAME_FOR_CSC)
  2683. {
  2684. SetLastError(ERROR_INVALID_PARAMETER);
  2685. return FALSE;
  2686. }
  2687. lstrcpy(tchBuff, lpszShareName);
  2688. if (!LpBreakPath(tchBuff, TRUE, &fDone) && !fDone)
  2689. {
  2690. SetLastError(ERROR_INVALID_PARAMETER);
  2691. return FALSE;
  2692. }
  2693. if (dwContext != 0)
  2694. {
  2695. WNetCancelConnection2(tchBuff, 0, TRUE);
  2696. }
  2697. return TRUE;
  2698. }
  2699. #if 0
  2700. BOOL
  2701. WINAPI
  2702. CSCEncryptDecryptFileW(
  2703. IN LPCTSTR lpszFileName,
  2704. IN BOOL fEncrypt
  2705. )
  2706. /*++
  2707. Routine Description:
  2708. Arguments:
  2709. Returns:
  2710. Notes:
  2711. --*/
  2712. {
  2713. WIN32_FIND_DATA sFind32;
  2714. SHADOWINFO sSI;
  2715. BOOL fRet = FALSE;
  2716. DWORD dwError = ERROR_GEN_FAILURE;
  2717. //
  2718. if(FindCreateShadowFromPath(lpszFileName, FALSE, &sFind32, &sSI, NULL))
  2719. {
  2720. fRet = RecreateShadow(INVALID_HANDLE_VALUE, sSI.hDir, sSI.hShadow, (fEncrypt)?FILE_ATTRIBUTE_ENCRYPTED:0);
  2721. }
  2722. return fRet;
  2723. }
  2724. #endif
  2725. BOOL
  2726. WINAPI
  2727. CSCQueryDatabaseStatus(
  2728. ULONG *pulStatus,
  2729. ULONG *pulErrors
  2730. )
  2731. /*++
  2732. Routine Description:
  2733. Allows caller to query the database status.
  2734. Arguments:
  2735. pulStatus Current status. Encryption status is the most interesting
  2736. pulErrors If the database has any errors, one or more bits will be set
  2737. Returns:
  2738. TRUE if the API succeeded
  2739. Notes:
  2740. --*/
  2741. {
  2742. GLOBALSTATUS sGS;
  2743. if(!GetGlobalStatus(INVALID_HANDLE_VALUE, &sGS))
  2744. {
  2745. return FALSE;
  2746. }
  2747. *pulStatus = sGS.sST.uFlags;
  2748. *pulErrors = sGS.uDatabaseErrorFlags;
  2749. return TRUE;
  2750. }
  2751. BOOL
  2752. WINAPI
  2753. CSCEncryptDecryptDatabase(
  2754. IN BOOL fEncrypt,
  2755. IN LPCSCPROCW lpfnEnumProgress,
  2756. IN DWORD_PTR dwContext
  2757. )
  2758. /*++
  2759. Routine Description:
  2760. This routine is used to encrypt/decrypt the entire database in system context. The routine checks that
  2761. the CSC database is hosted on a filesystem that allows encryption. Only admins can do the conversion
  2762. Arguments:
  2763. fEncrypt if TRUE, we encrypt the database else we decrypt.
  2764. LPCSCPROCW callback proc. The usual set of CSCPROC_REASON_BEGIN, CSCPROC_REASON_MORE_DATA, CSC_PROC_END
  2765. are sent when the conversion actually begins. Conversion can fail if a file is open or for
  2766. some other reason, in which case the second to last parameter in the callback with
  2767. CSCPROC_REASON_MORE_DATA has the error code. The third to last parameter indicates whether
  2768. the conversion was complete or not. Incomplete conversion is not an error condition.
  2769. dwContext callback context
  2770. Returns:
  2771. TRUE if no errors encountered.
  2772. Notes:
  2773. Theory of operations:
  2774. The CSC database encryption code encrypts all the inodes represented by remote files.
  2775. Who: Only user in admingroup can do encryption/decryption. This is checked in kernel
  2776. Which context: Files are encrypted in system context. This allows files to be shared
  2777. while still being encrypted. This solution protects from a stolen laptop case.
  2778. The database can have the following status set on it based on the four encryption states:
  2779. a) FLAG_DATABASESTATUS_UNENCRYPTED b) FLAG_DATABASESTATUS_PARTIALLY_UNENCRYPTED
  2780. c) FLAG_DATABASESTATUS_ENCRYPTED d) FLAG_DATABASESTATUS_PARTIALLY_ENCRYPTED
  2781. In states a) and b) new files are created unencrypted. In states c) and d) new files are created encrypted.
  2782. At the beginning of the conversion, the database stats is marked to the appropriate XX_PARTIAL_XX
  2783. state. At the end, if all goes well, it is transitioned to the final state.
  2784. At the time of enabling CSC, if the database state is XX_PARTIAL_XX, the kernel code tries to
  2785. complete the conversion to the appropriate final state.
  2786. --*/
  2787. {
  2788. BOOL fRet = FALSE, fComplete = FALSE;
  2789. HANDLE hShadowDB = INVALID_HANDLE_VALUE;
  2790. SHADOWSTORE sST;
  2791. DWORD dwRet, dwError=0, dwStartigNameSpaceVersion;
  2792. ULONG uT;
  2793. WIN32_FIND_DATA sFind32;
  2794. ENCRYPT_DECRYPT_SUBTREE sEDS;
  2795. SHADOWINFO sSI;
  2796. HANDLE ulEnumCookie;
  2797. // we have begun
  2798. if (lpfnEnumProgress)
  2799. {
  2800. dwRet = (*lpfnEnumProgress)(NULL, 0, 0, 0, NULL, CSCPROC_REASON_BEGIN, fEncrypt, 0, dwContext);
  2801. if (dwRet != CSCPROC_RETURN_CONTINUE )
  2802. {
  2803. goto bailout;
  2804. }
  2805. }
  2806. if (GetShadowDatabaseLocation(INVALID_HANDLE_VALUE, &sFind32))
  2807. {
  2808. // Set NULL after the root backslash so that this API works correctly
  2809. sFind32.cFileName[3] = 0;
  2810. if(!GetVolumeInformation(sFind32.cFileName, NULL, 0, NULL, &dwRet, &dwError, NULL, 0))
  2811. {
  2812. ReintKdPrint(BADERRORS, ("failed to get volume info for %ls Error=%d\r\n", sFind32.cFileName, GetLastError()));
  2813. goto bailout;
  2814. }
  2815. if (!(dwError & FILE_SUPPORTS_ENCRYPTION))
  2816. {
  2817. ReintKdPrint(BADERRORS, ("volume doesn't support replication \r\n"));
  2818. SetLastError(ERROR_NOT_SUPPORTED);
  2819. goto bailout;
  2820. }
  2821. }
  2822. else
  2823. {
  2824. ReintKdPrint(BADERRORS, ("failed to get database location Error=%d\r\n", GetLastError()));
  2825. goto bailout;
  2826. }
  2827. if ((hShadowDB = OpenShadowDatabaseIO())==INVALID_HANDLE_VALUE)
  2828. {
  2829. goto bailout;
  2830. }
  2831. // let us see whether we need to do anything
  2832. if(!GetSpaceStats(hShadowDB, &sST))
  2833. {
  2834. goto bailout;
  2835. }
  2836. sST.uFlags &= FLAG_DATABASESTATUS_ENCRYPTION_MASK;
  2837. // the database is already in the state desired, succeed and quit
  2838. if ((fEncrypt && (sST.uFlags == FLAG_DATABASESTATUS_ENCRYPTED))||
  2839. (!fEncrypt && (sST.uFlags == FLAG_DATABASESTATUS_UNENCRYPTED)))
  2840. {
  2841. fRet = TRUE;
  2842. goto bailout;
  2843. }
  2844. sST.uFlags = (fEncrypt)? FLAG_DATABASESTATUS_PARTIALLY_ENCRYPTED : FLAG_DATABASESTATUS_PARTIALLY_UNENCRYPTED;
  2845. // mark the database in appropriate transient state
  2846. // once this is marked, any new file that is created is in correct encryption state
  2847. if (!SetDatabaseStatus(hShadowDB, sST.uFlags, FLAG_DATABASESTATUS_ENCRYPTION_MASK))
  2848. {
  2849. goto bailout;
  2850. }
  2851. memset(&sEDS, 0, sizeof(sEDS));
  2852. memset(&sFind32, 0, sizeof(sFind32));
  2853. lstrcpy(sFind32.cFileName, _TEXT("*"));
  2854. if(!FindOpenShadow( hShadowDB, 0, FINDOPEN_SHADOWINFO_ALL,
  2855. &sFind32, &sSI))
  2856. {
  2857. // The database is empty, so set the state to fully encrypted (or decrypted)
  2858. sST.uFlags = (fEncrypt)? FLAG_DATABASESTATUS_ENCRYPTED : FLAG_DATABASESTATUS_UNENCRYPTED;
  2859. SetDatabaseStatus(hShadowDB, sST.uFlags, FLAG_DATABASESTATUS_ENCRYPTION_MASK);
  2860. goto bailout;
  2861. }
  2862. dwStartigNameSpaceVersion = sSI.dwNameSpaceVersion;
  2863. ulEnumCookie = sSI.uEnumCookie;
  2864. sEDS.dwContext = dwContext;
  2865. sEDS.lpfnEnumProgress = lpfnEnumProgress;
  2866. sEDS.fEncrypt = fEncrypt;
  2867. ReintKdPrint(ALWAYS, ("Starting NameSpaceVersion %x \n", dwStartigNameSpaceVersion));
  2868. do {
  2869. if(TraverseOneDirectory(hShadowDB, NULL, sSI.hDir, sSI.hShadow, sFind32.cFileName, EncryptDecryptSubtree, &sEDS)==TOD_ABORT)
  2870. {
  2871. break;
  2872. }
  2873. }while(FindNextShadow(hShadowDB, ulEnumCookie, &sFind32, &sSI));
  2874. FindCloseShadow(hShadowDB, ulEnumCookie);
  2875. ReintKdPrint(ALWAYS, ("Ending NameSpaceVersion %x \n", sEDS.dwEndingNameSpaceVersion));
  2876. if (!(sEDS.dwFlags & EDS_FLAG_ERROR_ENCOUNTERED) &&
  2877. (dwStartigNameSpaceVersion == sEDS.dwEndingNameSpaceVersion))
  2878. {
  2879. sST.uFlags = (fEncrypt)? FLAG_DATABASESTATUS_ENCRYPTED : FLAG_DATABASESTATUS_UNENCRYPTED;
  2880. if (!SetDatabaseStatus(hShadowDB, sST.uFlags, FLAG_DATABASESTATUS_ENCRYPTION_MASK))
  2881. {
  2882. goto bailout;
  2883. }
  2884. fComplete = TRUE;
  2885. }
  2886. dwError = NO_ERROR;
  2887. fRet = TRUE;
  2888. bailout:
  2889. if (!fRet)
  2890. {
  2891. dwError = GetLastError();
  2892. }
  2893. if (hShadowDB != INVALID_HANDLE_VALUE)
  2894. {
  2895. CloseShadowDatabaseIO(hShadowDB);
  2896. }
  2897. if (lpfnEnumProgress)
  2898. {
  2899. dwRet = (*lpfnEnumProgress)(NULL, 0, 0, 0, NULL, CSCPROC_REASON_END, fComplete, dwError, dwContext);
  2900. }
  2901. return fRet;
  2902. }
  2903. int
  2904. EncryptDecryptSubtree(
  2905. HANDLE hShadowDB,
  2906. LPSECURITYINFO pShareSecurityInfo,
  2907. LPTSTR lptzFullPath,
  2908. DWORD dwCallbackReason,
  2909. WIN32_FIND_DATA *lpFind32,
  2910. SHADOWINFO *lpSI,
  2911. LPENCRYPT_DECRYPT_SUBTREE lpEds
  2912. )
  2913. /*++
  2914. Routine Description:
  2915. This is a callback routine to TraverseOneDirectory. It encrypts or decrypts files in the subtree
  2916. Arguments:
  2917. hShadowDB Handle to issue ioctls to the redir
  2918. lptzFullPath fully qualified path to the item
  2919. dwCallbackReason TOD_CALLBACK_REASON_XXX (BEGIN, NEXT_ITEM or END)
  2920. lpFind32 local win32info
  2921. lpSI other info such as priority, pincount etc.
  2922. lpEds ENCRYPT_DECRYPT_SUBTREE structure which contains the relevant info such
  2923. as encrypt-or-decrypt, callback function, context, error flag
  2924. Returns:
  2925. return code, whether continue, cancel etc.
  2926. Notes:
  2927. --*/
  2928. {
  2929. BOOL fRet;
  2930. DWORD dwError, dwRet;
  2931. int iRet = TOD_CONTINUE;
  2932. //Bug: 581224
  2933. // Should return TOD_CONTINUE for TOD_CALLBACK_REASON_BEGIN
  2934. if (dwCallbackReason == TOD_CALLBACK_REASON_BEGIN) {
  2935. return iRet;
  2936. }
  2937. // save the last known version number, the calling routine will
  2938. // compare it against the first one
  2939. if(dwCallbackReason == TOD_CALLBACK_REASON_NEXT_ITEM)
  2940. {
  2941. lpEds->dwEndingNameSpaceVersion = lpSI->dwNameSpaceVersion;
  2942. }
  2943. // operate only on files
  2944. if (lpSI->uStatus & SHADOW_IS_FILE)
  2945. {
  2946. ReintKdPrint(ALWAYS, ("Processing file %ls \n", lptzFullPath));
  2947. do
  2948. {
  2949. dwError = 0;
  2950. // try conversion. If we fail, not in the EDS structure so
  2951. // the caller knows
  2952. if(!RecreateShadow(hShadowDB, lpSI->hDir, lpSI->hShadow, (lpEds->fEncrypt)?FILE_ATTRIBUTE_ENCRYPTED:0))
  2953. {
  2954. dwError = GetLastError();
  2955. }
  2956. if (lpEds->lpfnEnumProgress)
  2957. {
  2958. dwRet = (*(lpEds->lpfnEnumProgress))(lptzFullPath, 0, 0, 0, lpFind32, CSCPROC_REASON_MORE_DATA, 0, dwError, lpEds->dwContext);
  2959. if (dwRet == CSCPROC_RETURN_RETRY)
  2960. {
  2961. continue;
  2962. }
  2963. // abort if the callback wants to
  2964. if (dwRet != CSCPROC_RETURN_CONTINUE )
  2965. {
  2966. iRet = TOD_ABORT;
  2967. }
  2968. }
  2969. break;
  2970. }
  2971. while (TRUE);
  2972. if (dwError != ERROR_SUCCESS)
  2973. {
  2974. lpEds->dwFlags |= EDS_FLAG_ERROR_ENCOUNTERED;
  2975. }
  2976. }
  2977. return iRet;
  2978. }
  2979. BOOL
  2980. CSCPurgeUnpinnedFiles(
  2981. ULONG Timeout,
  2982. PULONG pnFiles,
  2983. PULONG pnYoungFiles)
  2984. {
  2985. BOOL iRet;
  2986. iRet = PurgeUnpinnedFiles(
  2987. INVALID_HANDLE_VALUE,
  2988. Timeout,
  2989. pnFiles,
  2990. pnYoungFiles);
  2991. // DbgPrint("CSCPurgeUnpinnedFiles(Timeout=%d nFiles=%d nYoungFiles=%d)\n",
  2992. // Timeout,
  2993. // *pnFiles,
  2994. // *pnYoungFiles);
  2995. return iRet;
  2996. }
  2997. BOOL
  2998. WINAPI
  2999. CSCShareIdToShareName(
  3000. ULONG ShareId,
  3001. PBYTE Buffer,
  3002. PDWORD pBufSize)
  3003. {
  3004. BOOL iRet;
  3005. iRet = ShareIdToShareName(
  3006. INVALID_HANDLE_VALUE,
  3007. ShareId,
  3008. Buffer,
  3009. pBufSize);
  3010. return iRet;
  3011. }
  3012. BOOL
  3013. IsPersonal(VOID)
  3014. {
  3015. OSVERSIONINFOEX Osvi;
  3016. DWORD TypeMask;
  3017. DWORDLONG ConditionMask;
  3018. memset(&Osvi, 0, sizeof(OSVERSIONINFOEX));
  3019. Osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  3020. Osvi.wSuiteMask = VER_SUITE_PERSONAL;
  3021. TypeMask = VER_SUITENAME;
  3022. ConditionMask = 0;
  3023. VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_OR);
  3024. return(VerifyVersionInfo(&Osvi, TypeMask, ConditionMask));
  3025. }