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.

621 lines
19 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: api.cxx
  7. //
  8. // Contents: Exported APIs from this DLL
  9. //
  10. // History: 5-Oct-95 BruceFo Created
  11. //
  12. //--------------------------------------------------------------------------
  13. #include "headers.hxx"
  14. #pragma hdrstop
  15. #include "resource.h"
  16. #include "dllmain.hxx"
  17. #include "shrpage.hxx"
  18. #include "shrinfo.hxx"
  19. #include "cache.hxx"
  20. #include "util.hxx"
  21. //+-------------------------------------------------------------------------
  22. //
  23. // Function: IsPathSharedW
  24. //
  25. // Synopsis: IsPathShared is used by the shell to determine whether to
  26. // put a "shared folder / hand" icon next to a directory.
  27. // Different from Windows 95, we don't allow sharing remote
  28. // directories (e.g., \\brucefo4\c$\foo\bar style paths).
  29. //
  30. // Arguments: [lpcszPath] - path to look for
  31. // [bRefresh] - TRUE if cache should be refreshed
  32. //
  33. // Returns: TRUE if the path is shared, FALSE otherwise
  34. //
  35. // History: 4-Apr-95 BruceFo Created
  36. //
  37. //--------------------------------------------------------------------------
  38. STDAPI_(BOOL)
  39. IsPathSharedW(
  40. LPCWSTR lpcszPath,
  41. BOOL bRefresh
  42. )
  43. {
  44. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  45. appDebugOut((DEB_TRACE,"IsPathSharedW(%ws, %d)\n", lpcszPath, bRefresh));
  46. OneTimeInit();
  47. BOOL bSuccess = g_ShareCache.IsPathShared(lpcszPath, bRefresh);
  48. appDebugOut((DEB_TRACE,
  49. "IsPathShared(%ws, %ws) = %ws\n",
  50. lpcszPath,
  51. bRefresh ? L"refresh" : L"no refresh",
  52. bSuccess ? L"yes" : L"no"));
  53. appAssert( 0 != g_NonOLEDLLRefs );
  54. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  55. return bSuccess;
  56. }
  57. //+-------------------------------------------------------------------------
  58. //
  59. // Function: IsPathSharedA
  60. //
  61. // Synopsis: See IsPathSharedW
  62. //
  63. // Arguments: See IsPathSharedW
  64. //
  65. // Returns: See IsPathSharedW
  66. //
  67. // History: 1-Mar-96 BruceFo Created
  68. // 27-Feb-02 JeffreyS Stubbed out
  69. //
  70. //--------------------------------------------------------------------------
  71. STDAPI_(BOOL)
  72. IsPathSharedA(
  73. LPCSTR /*lpcszPath*/,
  74. BOOL /*bRefresh*/
  75. )
  76. {
  77. SetLastError(ERROR_NOT_SUPPORTED);
  78. return FALSE;
  79. }
  80. //+-------------------------------------------------------------------------
  81. //
  82. // Function: SharingDialog
  83. //
  84. // Synopsis: This API brings up the "Sharing" dialog. This entrypoint is
  85. // only used by the FAX team, as far as I know. Note that the
  86. // paths passed in are ANSI---that's because that's what they
  87. // were in Win95 when the API was defined.
  88. //
  89. // This API, on NT, only works locally. It does not do remote
  90. // sharing, as Win95 does. Thus, the pszComputerName parameter
  91. // is ignored.
  92. //
  93. // Arguments: hwndParent -- parent window
  94. // pszComputerName -- a computer name. This is ignored!
  95. // pszPath -- the path to share.
  96. //
  97. // Returns: TRUE if everything went OK, FALSE otherwise
  98. //
  99. // History: 5-Oct-95 BruceFo Created
  100. //
  101. //--------------------------------------------------------------------------
  102. STDAPI_(BOOL)
  103. SharingDialogW(
  104. HWND hwndParent,
  105. LPCWSTR pszComputerName,
  106. LPCWSTR pszPath
  107. )
  108. {
  109. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  110. appDebugOut((DEB_TRACE,"SharingDialogW(%ws)\n", pszPath));
  111. BOOL bReturn = FALSE;
  112. // Parameter validation
  113. if (NULL != pszComputerName)
  114. {
  115. appDebugOut((DEB_TRACE,
  116. "SharingDialog() API called with a computer name which will be ignored\n"));
  117. }
  118. if (NULL != pszPath)
  119. {
  120. // Make sure the DLL is initialized.
  121. OneTimeInit(TRUE);
  122. CSharingPropertyPage* pPage = new CSharingPropertyPage(TRUE);
  123. if (NULL != pPage)
  124. {
  125. HRESULT hr = pPage->InitInstance(pszPath);
  126. if (SUCCEEDED(hr))
  127. {
  128. PROPSHEETPAGE psp;
  129. psp.dwSize = sizeof(psp); // no extra data.
  130. psp.dwFlags = PSP_USEREFPARENT | PSP_USECALLBACK;
  131. psp.hInstance = g_hInstance;
  132. psp.pszTemplate = MAKEINTRESOURCE(IDD_SHARE_PROPERTIES);
  133. psp.hIcon = NULL;
  134. psp.pszTitle = NULL;
  135. psp.pfnDlgProc = CSharingPropertyPage::DlgProcPage;
  136. psp.lParam = (LPARAM)pPage; // transfer ownership
  137. psp.pfnCallback = CSharingPropertyPage::PageCallback;
  138. psp.pcRefParent = &g_NonOLEDLLRefs;
  139. INT_PTR ret = DialogBoxParam(
  140. g_hInstance,
  141. MAKEINTRESOURCE(IDD_SHARE_PROPERTIES),
  142. hwndParent,
  143. CSharingPropertyPage::DlgProcPage,
  144. (LPARAM)&psp);
  145. if (-1 != ret)
  146. {
  147. bReturn = TRUE;
  148. }
  149. }
  150. pPage->Release();
  151. }
  152. }
  153. appAssert( 0 != g_NonOLEDLLRefs );
  154. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  155. return bReturn;
  156. }
  157. //+-------------------------------------------------------------------------
  158. //
  159. // Function: SharingDialogA
  160. //
  161. // Synopsis: see SharingDialogW
  162. //
  163. // Arguments: see SharingDialogW
  164. //
  165. // Returns: see SharingDialogW
  166. //
  167. // History: 1-Mar-96 BruceFo Created
  168. // 27-Feb-02 JeffreyS Stubbed out
  169. //
  170. //--------------------------------------------------------------------------
  171. STDAPI_(BOOL)
  172. SharingDialogA(
  173. HWND /*hwndParent*/,
  174. LPCSTR /*pszComputerName*/,
  175. LPCSTR /*pszPath*/
  176. )
  177. {
  178. SetLastError(ERROR_NOT_SUPPORTED);
  179. return FALSE;
  180. }
  181. DWORD
  182. CopyShareNameToBuffer(
  183. IN CShareInfo* p,
  184. IN OUT LPWSTR lpszNameBuf,
  185. IN DWORD cchNameBufLen
  186. )
  187. {
  188. appAssert(NULL != lpszNameBuf);
  189. appAssert(0 != cchNameBufLen);
  190. WCHAR szLocalComputer[MAX_COMPUTERNAME_LENGTH + 1];
  191. DWORD nSize = ARRAYLEN(szLocalComputer);
  192. if (!GetComputerName(szLocalComputer, &nSize))
  193. {
  194. return GetLastError();
  195. }
  196. DWORD computerLen = lstrlenW(szLocalComputer);
  197. DWORD shareLen = lstrlenW(p->GetNetname());
  198. /* Two slashes + server name + slash + share name + null terminator. */
  199. if (2 + computerLen + 1 + shareLen + 1 > cchNameBufLen)
  200. {
  201. return ERROR_MORE_DATA;
  202. }
  203. /* Return network resource name as UNC path. */
  204. lpszNameBuf[0] = L'\\';
  205. lpszNameBuf[1] = L'\\';
  206. lpszNameBuf += 2;
  207. cchNameBufLen -= 2;
  208. lstrcpynW(lpszNameBuf, szLocalComputer, cchNameBufLen);
  209. lpszNameBuf += computerLen;
  210. cchNameBufLen -= computerLen;
  211. *lpszNameBuf++ = L'\\';
  212. cchNameBufLen--;
  213. lstrcpynW(lpszNameBuf, p->GetNetname(), cchNameBufLen);
  214. return ERROR_SUCCESS;
  215. }
  216. //+-------------------------------------------------------------------------
  217. //
  218. // Function: GetNetResourceFromLocalPathW
  219. //
  220. // Synopsis: Used by shell link tracking code.
  221. //
  222. // Arguments: [lpcszPath] Path we're concerned about.
  223. // [lpszNameBuf] If path is shared, UNC path to share goes here.
  224. // [cchNameBufLen] length of lpszNameBuf buffer in characters
  225. // [pdwNetType] net type of local server, e.g., WNNC_NET_LANMAN
  226. //
  227. // Returns: TRUE if path is shared and net resource information
  228. // returned, else FALSE.
  229. //
  230. // Notes: *lpszNameBuf and *pwNetType are only valid if TRUE is returned.
  231. //
  232. // Example: If c:\documents is shared as MyDocs on machine Scratch, then
  233. // calling GetNetResourceFromLocalPath(c:\documents, ...) will
  234. // set lpszNameBuf to \\Scratch\MyDocs.
  235. //
  236. // History: 3-Mar-96 BruceFo Created from Win95 sources
  237. //
  238. //--------------------------------------------------------------------------
  239. STDAPI_(BOOL)
  240. GetNetResourceFromLocalPathW(
  241. IN LPCWSTR lpcszPath,
  242. IN OUT LPWSTR lpszNameBuf,
  243. IN DWORD cchNameBufLen,
  244. OUT PDWORD pdwNetType
  245. )
  246. {
  247. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  248. appDebugOut((DEB_TRACE,"GetNetResourceFromLocalPathW(%ws)\n", lpcszPath));
  249. // do some parameter validation
  250. if (NULL == lpcszPath || NULL == lpszNameBuf || NULL == pdwNetType || 0 == cchNameBufLen)
  251. {
  252. SetLastError(ERROR_OUTOFMEMORY);
  253. appAssert( 0 != g_NonOLEDLLRefs );
  254. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  255. return FALSE;
  256. }
  257. OneTimeInit();
  258. // Parameters seem OK (pointers might still point to bad memory);
  259. // do the work.
  260. CShareInfo* pShareList = new CShareInfo(); // dummy head node
  261. if (NULL == pShareList)
  262. {
  263. SetLastError(ERROR_OUTOFMEMORY);
  264. appAssert( 0 != g_NonOLEDLLRefs );
  265. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  266. return FALSE; // out of memory
  267. }
  268. BOOL bReturn = FALSE;
  269. DWORD dwLastError;
  270. DWORD cShares;
  271. HRESULT hr = g_ShareCache.ConstructList(lpcszPath, pShareList, &cShares);
  272. if (SUCCEEDED(hr))
  273. {
  274. // Now, we have a list of (possibly zero) shares. The user is asking for
  275. // one of them. Give them the first normal, non-special share. If there
  276. // doesn't exist a non-special share, then give them a special share.
  277. if (cShares > 0)
  278. {
  279. BOOL bFoundOne = FALSE;
  280. CShareInfo* p;
  281. for (p = (CShareInfo*) pShareList->Next();
  282. p != pShareList;
  283. p = (CShareInfo*) p->Next())
  284. {
  285. if (p->GetType() == STYPE_DISKTREE)
  286. {
  287. // found a share for this one.
  288. bFoundOne = TRUE;
  289. break;
  290. }
  291. }
  292. if (!bFoundOne)
  293. {
  294. for (p = (CShareInfo*) pShareList->Next();
  295. p != pShareList;
  296. p = (CShareInfo*) p->Next())
  297. {
  298. if (p->GetType() == (STYPE_SPECIAL | STYPE_DISKTREE))
  299. {
  300. bFoundOne = TRUE;
  301. break;
  302. }
  303. }
  304. }
  305. if (bFoundOne)
  306. {
  307. dwLastError = CopyShareNameToBuffer(p, lpszNameBuf, cchNameBufLen);
  308. if (ERROR_SUCCESS == dwLastError)
  309. {
  310. bReturn = TRUE;
  311. *pdwNetType = WNNC_NET_LANMAN; // we only support LanMan
  312. }
  313. }
  314. else
  315. {
  316. // nothing found!
  317. dwLastError = ERROR_BAD_NET_NAME;
  318. }
  319. }
  320. else
  321. {
  322. dwLastError = ERROR_BAD_NET_NAME;
  323. }
  324. }
  325. else
  326. {
  327. dwLastError = ERROR_OUTOFMEMORY;
  328. }
  329. DeleteShareInfoList(pShareList, TRUE);
  330. if (!bReturn)
  331. {
  332. SetLastError(dwLastError);
  333. }
  334. appAssert( 0 != g_NonOLEDLLRefs );
  335. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  336. return bReturn;
  337. }
  338. STDAPI_(BOOL)
  339. GetNetResourceFromLocalPathA(
  340. IN LPCSTR /*lpcszPath*/,
  341. IN OUT LPSTR /*lpszNameBuf*/,
  342. IN DWORD /*cchNameBufLen*/,
  343. OUT PDWORD /*pdwNetType*/
  344. )
  345. {
  346. SetLastError(ERROR_NOT_SUPPORTED);
  347. return FALSE;
  348. }
  349. //+-------------------------------------------------------------------------
  350. //
  351. // Function: GetLocalPathFromNetResourceW
  352. //
  353. // Synopsis: Used by shell link tracking code.
  354. //
  355. // Arguments: [lpcszName] A UNC path we're concerned about.
  356. // [dwNetType] net type of local server, e.g., WNNC_NET_LANMAN
  357. // [lpszLocalPathBuf] Buffer to place local path of UNC path
  358. // [cchLocalPathBufLen] length of lpszLocalPathBuf buffer in
  359. // characters
  360. // [pbIsLocal] Set to TRUE if lpcszName points to a local
  361. // resource.
  362. //
  363. // Returns:
  364. //
  365. // Notes: *lpszLocalPathBuf and *pbIsLocal are only valid if
  366. // TRUE is returned.
  367. //
  368. // Example: If c:\documents is shared as MyDocs on machine Scratch, then
  369. // calling GetLocalPathFromNetResource(\\Scratch\MyDocs, ...) will
  370. // set lpszLocalPathBuf to c:\documents.
  371. //
  372. // History: 3-Mar-96 BruceFo Created from Win95 sources
  373. //
  374. //--------------------------------------------------------------------------
  375. STDAPI_(BOOL)
  376. GetLocalPathFromNetResourceW(
  377. IN LPCWSTR lpcszName,
  378. IN DWORD dwNetType,
  379. IN OUT LPWSTR lpszLocalPathBuf,
  380. IN DWORD cchLocalPathBufLen,
  381. OUT PBOOL pbIsLocal
  382. )
  383. {
  384. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  385. appDebugOut((DEB_TRACE,"GetLocalPathFromNetResourceW(%ws)\n", lpcszName));
  386. OneTimeInit();
  387. BOOL bReturn = FALSE;
  388. DWORD dwLastError;
  389. *pbIsLocal = FALSE;
  390. if (g_fSharingEnabled)
  391. {
  392. if (0 != dwNetType && HIWORD(dwNetType) == HIWORD(WNNC_NET_LANMAN))
  393. {
  394. /* Is the network resource name a UNC path on this machine? */
  395. WCHAR szLocalComputer[MAX_COMPUTERNAME_LENGTH + 1];
  396. DWORD nSize = ARRAYLEN(szLocalComputer);
  397. if (!GetComputerName(szLocalComputer, &nSize))
  398. {
  399. dwLastError = GetLastError();
  400. }
  401. else
  402. {
  403. dwLastError = ERROR_BAD_NET_NAME;
  404. DWORD dwLocalComputerLen = lstrlenW(szLocalComputer);
  405. if ( lpcszName[0] == L'\\'
  406. && lpcszName[1] == L'\\'
  407. && (0 == _wcsnicmp(lpcszName + 2, szLocalComputer, dwLocalComputerLen))
  408. )
  409. {
  410. LPCWSTR lpcszSep = &(lpcszName[2 + dwLocalComputerLen]);
  411. if (*lpcszSep == L'\\')
  412. {
  413. *pbIsLocal = TRUE;
  414. WCHAR szLocalPath[MAX_PATH];
  415. if (g_ShareCache.IsExistingShare(lpcszSep + 1, NULL, szLocalPath, ARRAYLEN(szLocalPath)))
  416. {
  417. if (wcslen(szLocalPath) < cchLocalPathBufLen)
  418. {
  419. lstrcpynW(lpszLocalPathBuf, szLocalPath, cchLocalPathBufLen);
  420. dwLastError = ERROR_SUCCESS;
  421. bReturn = TRUE;
  422. }
  423. else
  424. {
  425. dwLastError = ERROR_MORE_DATA;
  426. }
  427. }
  428. }
  429. }
  430. }
  431. }
  432. else
  433. {
  434. dwLastError = ERROR_BAD_PROVIDER;
  435. }
  436. }
  437. else
  438. {
  439. appDebugOut((DEB_TRACE,"GetLocalPathFromNetResourceW: sharing not enabled\n"));
  440. dwLastError = ERROR_BAD_NET_NAME;
  441. }
  442. if (!bReturn)
  443. {
  444. SetLastError(dwLastError);
  445. }
  446. appAssert( 0 != g_NonOLEDLLRefs );
  447. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  448. return bReturn;
  449. }
  450. STDAPI_(BOOL)
  451. GetLocalPathFromNetResourceA(
  452. IN LPCSTR /*lpcszName*/,
  453. IN DWORD /*dwNetType*/,
  454. IN OUT LPSTR /*lpszLocalPathBuf*/,
  455. IN DWORD /*cchLocalPathBufLen*/,
  456. OUT PBOOL /*pbIsLocal*/
  457. )
  458. {
  459. SetLastError(ERROR_NOT_SUPPORTED);
  460. return FALSE;
  461. }
  462. STDAPI CanShareFolderW(LPCWSTR pszPath)
  463. {
  464. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  465. appDebugOut((DEB_TRACE,"CanShareFolderW(%s)\n", pszPath));
  466. OneTimeInit();
  467. HRESULT hr = S_FALSE;
  468. if (g_fSharingEnabled || IsSimpleUI())
  469. {
  470. if ( (pszPath[0] >= L'A' && pszPath[0] <= L'Z') && pszPath[1] == L':')
  471. {
  472. WCHAR szRoot[4];
  473. szRoot[0] = pszPath[0];
  474. szRoot[1] = TEXT(':');
  475. szRoot[2] = TEXT('\\');
  476. szRoot[3] = 0;
  477. UINT uType = GetDriveType(szRoot);
  478. switch (uType)
  479. {
  480. case DRIVE_UNKNOWN:
  481. case DRIVE_NO_ROOT_DIR:
  482. case DRIVE_REMOTE:
  483. hr = S_FALSE;
  484. break;
  485. case DRIVE_FIXED:
  486. case DRIVE_REMOVABLE:
  487. {
  488. WCHAR szDesktopIni[MAX_PATH];
  489. if (PathCombine(szDesktopIni, pszPath, TEXT("desktop.ini")))
  490. {
  491. hr = GetPrivateProfileInt(TEXT(".ShellClassInfo"), TEXT("Sharing"), TRUE, szDesktopIni) ? S_OK : S_FALSE;
  492. }
  493. else
  494. {
  495. hr = HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE);
  496. }
  497. }
  498. break;
  499. default:
  500. hr = S_OK;
  501. break;
  502. }
  503. //
  504. // NTRAID#NTBUG9-353119-2001/04/10-jeffreys
  505. //
  506. // We need to call PathIsDirectory to prevent the "Share this
  507. // folder" task from appearing in the webview pane of CAB and
  508. // ZIP folders. (NTBUG9 #319149 and 319153)
  509. //
  510. // However, PathIsDirectory fails with ERROR_NOT_READY on an
  511. // empty CD or removable drive, which is a case we want to allow
  512. // or the Sharing page will not show. (NTBUG9 #353119)
  513. //
  514. if (S_OK == hr && !PathIsDirectory(pszPath))
  515. {
  516. hr = S_FALSE;
  517. if (GetLastError() == ERROR_NOT_READY &&
  518. (DRIVE_CDROM == uType || DRIVE_REMOVABLE == uType) &&
  519. PathIsRootW(pszPath))
  520. {
  521. // Ok to share an empty CD or removable drive
  522. hr = S_OK;
  523. }
  524. }
  525. }
  526. }
  527. appAssert( 0 != g_NonOLEDLLRefs );
  528. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  529. return hr;
  530. }
  531. STDAPI ShowShareFolderUIW(HWND hwndParent, LPCWSTR pszPath)
  532. {
  533. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  534. appDebugOut((DEB_TRACE,"ShowShareFolderUIW(%s)\n", pszPath));
  535. TCHAR szShare[50];
  536. LoadString(g_hInstance, IDS_MSGTITLE, szShare, ARRAYLEN(szShare));
  537. SHObjectProperties(hwndParent, SHOP_FILEPATH, pszPath, szShare);
  538. appAssert( 0 != g_NonOLEDLLRefs );
  539. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  540. return S_OK;
  541. }