Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

805 lines
24 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. static BOOL WINAPI
  23. SharingDialogHelp(
  24. HWND hwndParent,
  25. LPWSTR pszPath // this is 'new' memory that I take ownership of
  26. );
  27. //--------------------------------------------------------------------------
  28. // A couple macros to use a stack buffer if smaller than a default size,
  29. // else use a heap buffer.
  30. // Example:
  31. // LPWSTR pBuffer;
  32. // DWORD dwBufLen;
  33. // GET_BUFFER(pBuffer, dwBufLen, WCHAR, wcslen(pszString) + 1, MAX_PATH);
  34. // if (NULL == pBuffer) { return NULL; } // couldn't get the buffer
  35. // ... play with pBuffer
  36. // FREE_BUFFER(pBuffer);
  37. #define GET_BUFFER(pBuffer, dwBufLen, type, desiredLen, defaultLen) \
  38. DWORD __desiredLen ## pBuffer = desiredLen; \
  39. type __szTmpBuffer ## pBuffer[defaultLen]; \
  40. if (__desiredLen ## pBuffer <= defaultLen) \
  41. { \
  42. pBuffer = __szTmpBuffer ## pBuffer; \
  43. dwBufLen = defaultLen; \
  44. } \
  45. else \
  46. { \
  47. pBuffer = new type[__desiredLen ## pBuffer]; \
  48. if (NULL != pBuffer) \
  49. { \
  50. dwBufLen = __desiredLen ## pBuffer; \
  51. } \
  52. }
  53. #define FREE_BUFFER(pBuffer) \
  54. if (__szTmpBuffer ## pBuffer != pBuffer) { delete[] pBuffer; }
  55. //--------------------------------------------------------------------------
  56. //+-------------------------------------------------------------------------
  57. //
  58. // Function: IsPathSharedW
  59. //
  60. // Synopsis: IsPathShared is used by the shell to determine whether to
  61. // put a "shared folder / hand" icon next to a directory.
  62. // Different from Windows 95, we don't allow sharing remote
  63. // directories (e.g., \\brucefo4\c$\foo\bar style paths).
  64. //
  65. // Arguments: [lpcszPath] - path to look for
  66. // [bRefresh] - TRUE if cache should be refreshed
  67. //
  68. // Returns: TRUE if the path is shared, FALSE otherwise
  69. //
  70. // History: 4-Apr-95 BruceFo Created
  71. //
  72. //--------------------------------------------------------------------------
  73. BOOL WINAPI
  74. IsPathSharedW(
  75. LPCWSTR lpcszPath,
  76. BOOL bRefresh
  77. )
  78. {
  79. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  80. appDebugOut((DEB_TRACE,"IsPathSharedW(%ws, %d)\n", lpcszPath, bRefresh));
  81. OneTimeInit();
  82. BOOL bSuccess = g_ShareCache.IsPathShared(lpcszPath, bRefresh);
  83. appDebugOut((DEB_TRACE,
  84. "IsPathShared(%ws, %ws) = %ws\n",
  85. lpcszPath,
  86. bRefresh ? L"refresh" : L"no refresh",
  87. bSuccess ? L"yes" : L"no"));
  88. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  89. return bSuccess;
  90. }
  91. //+-------------------------------------------------------------------------
  92. //
  93. // Function: IsPathSharedA
  94. //
  95. // Synopsis: See IsPathSharedW
  96. //
  97. // Arguments: See IsPathSharedW
  98. //
  99. // Returns: See IsPathSharedW
  100. //
  101. // History: 1-Mar-96 BruceFo Created
  102. //
  103. //--------------------------------------------------------------------------
  104. BOOL WINAPI
  105. IsPathSharedA(
  106. LPCSTR lpcszPath,
  107. BOOL bRefresh
  108. )
  109. {
  110. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  111. appDebugOut((DEB_TRACE,"IsPathSharedA(%s, %d)\n", lpcszPath, bRefresh));
  112. if (NULL == lpcszPath)
  113. {
  114. return FALSE; // invalid input!
  115. }
  116. LPWSTR pszTmp;
  117. DWORD dwBufLen;
  118. GET_BUFFER(pszTmp, dwBufLen, WCHAR, lstrlenA(lpcszPath) + 1, MAX_PATH);
  119. if (NULL == pszTmp)
  120. {
  121. return FALSE; // didn't get the buffer
  122. }
  123. MultiByteToWideChar(CP_ACP, 0, lpcszPath, -1, pszTmp, dwBufLen);
  124. BOOL bReturn = IsPathSharedW(pszTmp, bRefresh);
  125. FREE_BUFFER(pszTmp);
  126. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  127. return bReturn;
  128. }
  129. //+-------------------------------------------------------------------------
  130. //
  131. // Function: SharingDialog
  132. //
  133. // Synopsis: This API brings up the "Sharing" dialog. This entrypoint is
  134. // only used by the FAX team, as far as I know. Note that the
  135. // paths passed in are ANSI---that's because that's what they
  136. // were in Win95 when the API was defined.
  137. //
  138. // This API, on NT, only works locally. It does not do remote
  139. // sharing, as Win95 does. Thus, the pszComputerName parameter
  140. // is ignored.
  141. //
  142. // Arguments: hwndParent -- parent window
  143. // pszComputerName -- a computer name. This is ignored!
  144. // pszPath -- the path to share.
  145. //
  146. // Returns: TRUE if everything went OK, FALSE otherwise
  147. //
  148. // History: 5-Oct-95 BruceFo Created
  149. //
  150. //--------------------------------------------------------------------------
  151. BOOL WINAPI
  152. SharingDialogW(
  153. HWND hwndParent,
  154. LPWSTR pszComputerName,
  155. LPWSTR pszPath
  156. )
  157. {
  158. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  159. appDebugOut((DEB_TRACE,"SharingDialogW(%ws)\n", pszPath));
  160. // Parameter validation
  161. if (NULL == pszPath)
  162. {
  163. return FALSE;
  164. }
  165. if (NULL != pszComputerName)
  166. {
  167. appDebugOut((DEB_TRACE,
  168. "SharingDialog() API called with a computer name which will be ignored\n"));
  169. }
  170. // Make sure the DLL is initialized. Note that this loads up the share
  171. // cache in this address space. Also, the first thing the dialog does
  172. // is refresh the cache, so we just wasted the work done to create the
  173. // cache in the init. Oh well...
  174. OneTimeInit(TRUE);
  175. PWSTR pszCopy = NewDup(pszPath);
  176. if (NULL == pszCopy)
  177. {
  178. return FALSE;
  179. }
  180. BOOL bReturn = SharingDialogHelp(hwndParent, pszCopy);
  181. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  182. return bReturn;
  183. }
  184. //+-------------------------------------------------------------------------
  185. //
  186. // Function: SharingDialogA
  187. //
  188. // Synopsis: see SharingDialogW
  189. //
  190. // Arguments: see SharingDialogW
  191. //
  192. // Returns: see SharingDialogW
  193. //
  194. // History: 1-Mar-96 BruceFo Created
  195. //
  196. //--------------------------------------------------------------------------
  197. BOOL WINAPI
  198. SharingDialogA(
  199. HWND hwndParent,
  200. LPSTR pszComputerName,
  201. LPSTR pszPath
  202. )
  203. {
  204. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  205. appDebugOut((DEB_TRACE,"SharingDialogA(%s)\n", pszPath));
  206. // Parameter validation
  207. if (NULL == pszPath)
  208. {
  209. return FALSE;
  210. }
  211. if (NULL != pszComputerName)
  212. {
  213. appDebugOut((DEB_TRACE,
  214. "SharingDialog() API called with a computer name which will be ignored\n"));
  215. }
  216. // Make sure the DLL is initialized. Note that this loads up the share
  217. // cache in this address space. Also, the first thing the dialog does
  218. // is refresh the cache, so we just wasted the work done to create the
  219. // cache in the init. Oh well...
  220. OneTimeInit(TRUE);
  221. DWORD dwLen = lstrlenA(pszPath) + 1;
  222. PWSTR pszUnicodePath = new WCHAR[dwLen];
  223. if (NULL == pszUnicodePath)
  224. {
  225. appDebugOut((DEB_ERROR,"OUT OF MEMORY\n"));
  226. return FALSE;
  227. }
  228. MultiByteToWideChar(CP_ACP, 0, pszPath, -1, pszUnicodePath, dwLen);
  229. BOOL bReturn = SharingDialogHelp(hwndParent, pszUnicodePath);
  230. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  231. return bReturn;
  232. }
  233. static BOOL WINAPI
  234. SharingDialogHelp(
  235. HWND hwndParent,
  236. LPWSTR pszPath // this is 'new' memory that I take ownership of
  237. )
  238. {
  239. CSharingPropertyPage* pPage = new CSharingPropertyPage(pszPath, TRUE);
  240. if (NULL == pPage)
  241. {
  242. delete[] pszPath;
  243. return FALSE;
  244. }
  245. HRESULT hr = pPage->InitInstance();
  246. if (FAILED(hr))
  247. {
  248. delete pPage;
  249. return FALSE;
  250. }
  251. PROPSHEETPAGE psp;
  252. psp.dwSize = sizeof(psp); // no extra data.
  253. psp.dwFlags = PSP_USEREFPARENT | PSP_USECALLBACK;
  254. psp.hInstance = g_hInstance;
  255. psp.pszTemplate = MAKEINTRESOURCE(IDD_SHARE_PROPERTIES);
  256. psp.hIcon = NULL;
  257. psp.pszTitle = NULL;
  258. psp.pfnDlgProc = CSharingPropertyPage::DlgProcPage;
  259. psp.lParam = (LPARAM)pPage; // transfer ownership
  260. psp.pfnCallback = CSharingPropertyPage::PageCallback;
  261. psp.pcRefParent = &g_NonOLEDLLRefs;
  262. INT_PTR ret = DialogBoxParam(
  263. g_hInstance,
  264. MAKEINTRESOURCE(IDD_SHARE_PROPERTIES),
  265. hwndParent,
  266. CSharingPropertyPage::DlgProcPage,
  267. (LPARAM)&psp);
  268. if (-1 == ret)
  269. {
  270. appDebugOut((DEB_ERROR,"DialogBoxParam() error, 0x%08lx\n",GetLastError()));
  271. delete pPage;
  272. return FALSE;
  273. }
  274. // Now we must simulate a property sheet destroy.
  275. CSharingPropertyPage::PageCallback(NULL, PSPCB_RELEASE, &psp);
  276. return TRUE;
  277. }
  278. // APPCOMPAT: there appears to be a bug in the Win95 code where they think
  279. // they're storing and using "\\machine\share", but it appears they are
  280. // actually storing and using "machine\share".
  281. DWORD
  282. CopyShareNameToBuffer(
  283. IN CShareInfo* p,
  284. IN OUT LPWSTR lpszNameBuf,
  285. IN DWORD cchNameBufLen
  286. )
  287. {
  288. appAssert(NULL != lpszNameBuf);
  289. appAssert(0 != cchNameBufLen);
  290. WCHAR szLocalComputer[MAX_COMPUTERNAME_LENGTH + 1];
  291. DWORD nSize = ARRAYLEN(szLocalComputer);
  292. if (!GetComputerName(szLocalComputer, &nSize))
  293. {
  294. return GetLastError();
  295. }
  296. /* Two slashes + server name + slash + share name + null terminator. */
  297. DWORD computerLen = wcslen(szLocalComputer);
  298. DWORD shareLen = wcslen(p->GetNetname());
  299. if (2 + computerLen + 1 + shareLen + 1 <= cchNameBufLen)
  300. {
  301. /* Return network resource name as UNC path. */
  302. lpszNameBuf[0] = L'\\';
  303. lpszNameBuf[1] = L'\\';
  304. wcscpy(lpszNameBuf + 2, szLocalComputer);
  305. *(lpszNameBuf + 2 + computerLen) = L'\\';
  306. wcscpy(lpszNameBuf + 2 + computerLen + 1, p->GetNetname());
  307. return ERROR_SUCCESS;
  308. }
  309. else
  310. {
  311. return ERROR_MORE_DATA;
  312. }
  313. }
  314. //+-------------------------------------------------------------------------
  315. //
  316. // Function: GetNetResourceFromLocalPathW
  317. //
  318. // Synopsis: Used by shell link tracking code.
  319. //
  320. // Arguments: [lpcszPath] Path we're concerned about.
  321. // [lpszNameBuf] If path is shared, UNC path to share goes here.
  322. // [cchNameBufLen] length of lpszNameBuf buffer in characters
  323. // [pdwNetType] net type of local server, e.g., WNNC_NET_LANMAN
  324. //
  325. // Returns: TRUE if path is shared and net resource information
  326. // returned, else FALSE.
  327. //
  328. // Notes: *lpszNameBuf and *pwNetType are only valid if TRUE is returned.
  329. //
  330. // Example: If c:\documents is shared as MyDocs on machine Scratch, then
  331. // calling GetNetResourceFromLocalPath(c:\documents, ...) will
  332. // set lpszNameBuf to \\Scratch\MyDocs.
  333. //
  334. // History: 3-Mar-96 BruceFo Created from Win95 sources
  335. //
  336. //--------------------------------------------------------------------------
  337. BOOL WINAPI
  338. GetNetResourceFromLocalPathW(
  339. IN LPCWSTR lpcszPath,
  340. IN OUT LPWSTR lpszNameBuf,
  341. IN DWORD cchNameBufLen,
  342. OUT PDWORD pdwNetType
  343. )
  344. {
  345. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  346. appDebugOut((DEB_TRACE,"GetNetResourceFromLocalPathW(%ws)\n", lpcszPath));
  347. // do some parameter validation
  348. if (NULL == lpcszPath || NULL == lpszNameBuf || NULL == pdwNetType || 0 == cchNameBufLen)
  349. {
  350. SetLastError(ERROR_OUTOFMEMORY);
  351. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  352. return FALSE;
  353. }
  354. OneTimeInit();
  355. // Parameters seem OK (pointers might still point to bad memory);
  356. // do the work.
  357. CShareInfo* pShareList = new CShareInfo(); // dummy head node
  358. if (NULL == pShareList)
  359. {
  360. SetLastError(ERROR_OUTOFMEMORY);
  361. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  362. return FALSE; // out of memory
  363. }
  364. BOOL bReturn = FALSE;
  365. DWORD dwLastError;
  366. DWORD cShares;
  367. HRESULT hr = g_ShareCache.ConstructList(lpcszPath, pShareList, &cShares);
  368. if (SUCCEEDED(hr))
  369. {
  370. // Now, we have a list of (possibly zero) shares. The user is asking for
  371. // one of them. Give them the first normal, non-special share. If there
  372. // doesn't exist a non-special share, then give them a special share.
  373. if (cShares > 0)
  374. {
  375. BOOL bFoundOne = FALSE;
  376. CShareInfo* p;
  377. for (p = (CShareInfo*) pShareList->Next();
  378. p != pShareList;
  379. p = (CShareInfo*) p->Next())
  380. {
  381. if (p->GetType() == STYPE_DISKTREE)
  382. {
  383. // found a share for this one.
  384. bFoundOne = TRUE;
  385. break;
  386. }
  387. }
  388. if (!bFoundOne)
  389. {
  390. for (p = (CShareInfo*) pShareList->Next();
  391. p != pShareList;
  392. p = (CShareInfo*) p->Next())
  393. {
  394. if (p->GetType() == (STYPE_SPECIAL | STYPE_DISKTREE))
  395. {
  396. bFoundOne = TRUE;
  397. break;
  398. }
  399. }
  400. }
  401. if (bFoundOne)
  402. {
  403. dwLastError = CopyShareNameToBuffer(p, lpszNameBuf, cchNameBufLen);
  404. if (ERROR_SUCCESS == dwLastError)
  405. {
  406. bReturn = TRUE;
  407. *pdwNetType = WNNC_NET_LANMAN; // we only support LanMan
  408. }
  409. }
  410. else
  411. {
  412. // nothing found!
  413. dwLastError = ERROR_BAD_NET_NAME;
  414. }
  415. }
  416. else
  417. {
  418. dwLastError = ERROR_BAD_NET_NAME;
  419. }
  420. }
  421. else
  422. {
  423. dwLastError = ERROR_OUTOFMEMORY;
  424. }
  425. DeleteShareInfoList(pShareList, TRUE);
  426. if (!bReturn)
  427. {
  428. SetLastError(dwLastError);
  429. }
  430. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  431. return bReturn;
  432. }
  433. BOOL WINAPI
  434. GetNetResourceFromLocalPathA(
  435. IN LPCSTR lpcszPath,
  436. IN OUT LPSTR lpszNameBuf,
  437. IN DWORD cchNameBufLen,
  438. OUT PDWORD pdwNetType
  439. )
  440. {
  441. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  442. appDebugOut((DEB_TRACE,"GetNetResourceFromLocalPathA(%s)\n", lpcszPath));
  443. BOOL bReturn = FALSE;
  444. LPWSTR pszPathTmp, pszNameTmp;
  445. DWORD dwPathBufLen, dwNameBufLen;
  446. GET_BUFFER(pszPathTmp, dwPathBufLen, WCHAR, lstrlenA(lpcszPath) + 1, MAX_PATH);
  447. if (NULL != pszPathTmp)
  448. {
  449. MultiByteToWideChar(CP_ACP, 0, lpcszPath, -1, pszPathTmp, dwPathBufLen);
  450. GET_BUFFER(pszNameTmp, dwNameBufLen, WCHAR, cchNameBufLen, MAX_PATH);
  451. if (NULL != pszNameTmp)
  452. {
  453. // got the buffers, now party...
  454. bReturn = GetNetResourceFromLocalPathW(pszPathTmp, pszNameTmp, cchNameBufLen, pdwNetType);
  455. if (bReturn)
  456. {
  457. // now convert the return string back
  458. WideCharToMultiByte(CP_ACP, 0,
  459. pszNameTmp, -1,
  460. lpszNameBuf, cchNameBufLen,
  461. NULL, NULL);
  462. }
  463. FREE_BUFFER(pszNameTmp);
  464. }
  465. else
  466. {
  467. // didn't get the buffer
  468. SetLastError(ERROR_OUTOFMEMORY);
  469. }
  470. FREE_BUFFER(pszPathTmp);
  471. }
  472. else
  473. {
  474. // didn't get the buffer
  475. SetLastError(ERROR_OUTOFMEMORY);
  476. }
  477. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  478. return bReturn;
  479. }
  480. //+-------------------------------------------------------------------------
  481. //
  482. // Function: GetLocalPathFromNetResourceW
  483. //
  484. // Synopsis: Used by shell link tracking code.
  485. //
  486. // Arguments: [lpcszName] A UNC path we're concerned about.
  487. // [dwNetType] net type of local server, e.g., WNNC_NET_LANMAN
  488. // [lpszLocalPathBuf] Buffer to place local path of UNC path
  489. // [cchLocalPathBufLen] length of lpszLocalPathBuf buffer in
  490. // characters
  491. // [pbIsLocal] Set to TRUE if lpcszName points to a local
  492. // resource.
  493. //
  494. // Returns:
  495. //
  496. // Notes: *lpszLocalPathBuf and *pbIsLocal are only valid if
  497. // TRUE is returned.
  498. //
  499. // Example: If c:\documents is shared as MyDocs on machine Scratch, then
  500. // calling GetLocalPathFromNetResource(\\Scratch\MyDocs, ...) will
  501. // set lpszLocalPathBuf to c:\documents.
  502. //
  503. // History: 3-Mar-96 BruceFo Created from Win95 sources
  504. //
  505. //--------------------------------------------------------------------------
  506. BOOL WINAPI
  507. GetLocalPathFromNetResourceW(
  508. IN LPCWSTR lpcszName,
  509. IN DWORD dwNetType,
  510. IN OUT LPWSTR lpszLocalPathBuf,
  511. IN DWORD cchLocalPathBufLen,
  512. OUT PBOOL pbIsLocal
  513. )
  514. {
  515. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  516. appDebugOut((DEB_TRACE,"GetLocalPathFromNetResourceW(%ws)\n", lpcszName));
  517. OneTimeInit();
  518. BOOL bReturn = FALSE;
  519. DWORD dwLastError;
  520. *pbIsLocal = FALSE;
  521. if (g_fSharingEnabled)
  522. {
  523. if (0 != dwNetType && HIWORD(dwNetType) == HIWORD(WNNC_NET_LANMAN))
  524. {
  525. /* Is the network resource name a UNC path on this machine? */
  526. WCHAR szLocalComputer[MAX_COMPUTERNAME_LENGTH + 1];
  527. DWORD nSize = ARRAYLEN(szLocalComputer);
  528. if (!GetComputerName(szLocalComputer, &nSize))
  529. {
  530. dwLastError = GetLastError();
  531. }
  532. else
  533. {
  534. dwLastError = ERROR_BAD_NET_NAME;
  535. DWORD dwLocalComputerLen = wcslen(szLocalComputer);
  536. if ( lpcszName[0] == L'\\'
  537. && lpcszName[1] == L'\\'
  538. && (0 == _wcsnicmp(lpcszName + 2, szLocalComputer, dwLocalComputerLen))
  539. )
  540. {
  541. LPCWSTR lpcszSep = &(lpcszName[2 + dwLocalComputerLen]);
  542. if (*lpcszSep == L'\\')
  543. {
  544. *pbIsLocal = TRUE;
  545. WCHAR szLocalPath[MAX_PATH];
  546. if (g_ShareCache.IsExistingShare(lpcszSep + 1, NULL, szLocalPath))
  547. {
  548. if (wcslen(szLocalPath) < cchLocalPathBufLen)
  549. {
  550. wcscpy(lpszLocalPathBuf, szLocalPath);
  551. dwLastError = ERROR_SUCCESS;
  552. bReturn = TRUE;
  553. }
  554. else
  555. {
  556. dwLastError = ERROR_MORE_DATA;
  557. }
  558. }
  559. }
  560. }
  561. }
  562. }
  563. else
  564. {
  565. dwLastError = ERROR_BAD_PROVIDER;
  566. }
  567. }
  568. else
  569. {
  570. appDebugOut((DEB_TRACE,"GetLocalPathFromNetResourceW: sharing not enabled\n"));
  571. dwLastError = ERROR_BAD_NET_NAME;
  572. }
  573. if (!bReturn)
  574. {
  575. SetLastError(dwLastError);
  576. }
  577. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  578. return bReturn;
  579. }
  580. BOOL WINAPI
  581. GetLocalPathFromNetResourceA(
  582. IN LPCSTR lpcszName,
  583. IN DWORD dwNetType,
  584. IN OUT LPSTR lpszLocalPathBuf,
  585. IN DWORD cchLocalPathBufLen,
  586. OUT PBOOL pbIsLocal
  587. )
  588. {
  589. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  590. appDebugOut((DEB_TRACE,"GetLocalPathFromNetResourceA(%s)\n", lpcszName));
  591. BOOL bReturn = FALSE;
  592. LPWSTR pszLocalPathTmp, pszNameTmp;
  593. DWORD dwPathBufLen, dwNameBufLen;
  594. GET_BUFFER(pszLocalPathTmp, dwPathBufLen, WCHAR, cchLocalPathBufLen, MAX_PATH);
  595. if (NULL != pszLocalPathTmp)
  596. {
  597. GET_BUFFER(pszNameTmp, dwNameBufLen, WCHAR, lstrlenA(lpszLocalPathBuf) + 1, MAX_PATH);
  598. if (NULL != pszNameTmp)
  599. {
  600. MultiByteToWideChar(CP_ACP, 0, lpcszName, -1, pszNameTmp, dwNameBufLen);
  601. // got the buffers, now party...
  602. bReturn = GetLocalPathFromNetResourceW(pszNameTmp, dwNetType, pszLocalPathTmp, cchLocalPathBufLen, pbIsLocal);
  603. if (bReturn)
  604. {
  605. // now convert the return string back
  606. WideCharToMultiByte(CP_ACP, 0,
  607. pszLocalPathTmp, -1,
  608. lpszLocalPathBuf, cchLocalPathBufLen,
  609. NULL, NULL);
  610. }
  611. FREE_BUFFER(pszNameTmp);
  612. }
  613. else
  614. {
  615. // didn't get the buffer
  616. SetLastError(ERROR_OUTOFMEMORY);
  617. }
  618. FREE_BUFFER(pszLocalPathTmp);
  619. }
  620. else
  621. {
  622. // didn't get the buffer
  623. SetLastError(ERROR_OUTOFMEMORY);
  624. }
  625. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  626. return bReturn;
  627. }
  628. STDAPI CanShareFolderW(LPCWSTR pszPath)
  629. {
  630. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  631. appDebugOut((DEB_TRACE,"CanShareFolderW(%s)\n", pszPath));
  632. OneTimeInit();
  633. HRESULT hr = S_FALSE;
  634. if (g_fSharingEnabled || IsSimpleUI())
  635. {
  636. if ( (pszPath[0] >= L'A' && pszPath[0] <= L'Z') && pszPath[1] == L':')
  637. {
  638. WCHAR szRoot[4];
  639. szRoot[0] = pszPath[0];
  640. szRoot[1] = TEXT(':');
  641. szRoot[2] = TEXT('\\');
  642. szRoot[3] = 0;
  643. UINT uType = GetDriveType(szRoot);
  644. switch (uType)
  645. {
  646. case DRIVE_UNKNOWN:
  647. case DRIVE_NO_ROOT_DIR:
  648. case DRIVE_REMOTE:
  649. hr = S_FALSE;
  650. break;
  651. case DRIVE_FIXED:
  652. case DRIVE_REMOVABLE:
  653. {
  654. WCHAR szDesktopIni[MAX_PATH];
  655. PathCombine(szDesktopIni, pszPath, TEXT("desktop.ini"));
  656. hr = GetPrivateProfileInt(TEXT(".ShellClassInfo"), TEXT("Sharing"), TRUE, szDesktopIni) ? S_OK : S_FALSE;
  657. }
  658. break;
  659. default:
  660. hr = S_OK;
  661. break;
  662. }
  663. //
  664. // NTRAID#NTBUG9-353119-2001/04/10-jeffreys
  665. //
  666. // We need to call PathIsDirectory to prevent the "Share this
  667. // folder" task from appearing in the webview pane of CAB and
  668. // ZIP folders. (NTBUG9 #319149 and 319153)
  669. //
  670. // However, PathIsDirectory fails with ERROR_NOT_READY on an
  671. // empty CD or removable drive, which is a case we want to allow
  672. // or the Sharing page will not show. (NTBUG9 #353119)
  673. //
  674. if (S_OK == hr && !PathIsDirectory(pszPath))
  675. {
  676. hr = S_FALSE;
  677. if (GetLastError() == ERROR_NOT_READY &&
  678. (DRIVE_CDROM == uType || DRIVE_REMOVABLE == uType) &&
  679. PathIsRootW(pszPath))
  680. {
  681. // Ok to share an empty CD or removable drive
  682. hr = S_OK;
  683. }
  684. }
  685. }
  686. }
  687. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  688. return hr;
  689. }
  690. STDAPI ShowShareFolderUIW(HWND hwndParent, LPCWSTR pszPath)
  691. {
  692. InterlockedIncrement((long*)&g_NonOLEDLLRefs);
  693. appDebugOut((DEB_TRACE,"ShowShareFolderUIW(%s)\n", pszPath));
  694. TCHAR szShare[50];
  695. LoadString(g_hInstance, IDS_MSGTITLE, szShare, ARRAYLEN(szShare));
  696. SHObjectProperties(hwndParent, SHOP_FILEPATH, pszPath, szShare);
  697. InterlockedDecrement((long*)&g_NonOLEDLLRefs);
  698. return S_OK;
  699. }