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.

649 lines
19 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: dynload.cxx
  7. //
  8. // Contents: APIs from dynamically loaded system dlls. These APIs
  9. // are rarely used and there are only 1 or 2 per system
  10. // Dll so we dynamically load the Dll so that we improve
  11. // the load time of OLE32.DLL
  12. //
  13. // Functions: OleWNetGetConnection
  14. // OleWNetGetUniversalName
  15. // OleExtractIcon
  16. // OleGetShellLink
  17. // OleSymInitialize
  18. // OleSymCleanup
  19. // OleSymGetSymFromAddr
  20. // OleSymUnDName
  21. //
  22. // History: 10-Jan-95 Rickhi Created
  23. // 10-Mar-95 BillMo Added OleGetShellLink-creates a shortcut object.
  24. // 12-Jul-95 t-stevan Added OleSym* routines
  25. // 22-Nov-95 MikeHill Use Unicode IShellLink object in NT.
  26. //
  27. //--------------------------------------------------------------------------
  28. #include <windows.h>
  29. #include <shellapi.h>
  30. #include <imagehlp.h>
  31. #include <ole2sp.h>
  32. #include <ole2com.h>
  33. #ifdef _CAIRO_
  34. #include <shlguid.h>
  35. #endif
  36. // Entry Points from MPR.DLL
  37. HINSTANCE hInstMPR = NULL;
  38. typedef DWORD (* PFN_WNETGETCONNECTION)(LPCTSTR lpLocalName, LPTSTR lpRemoteName, LPDWORD lpnLength);
  39. PFN_WNETGETCONNECTION pfnWNetGetConnection = NULL;
  40. #ifdef _CHICAGO_
  41. #define WNETGETCONNECTION_NAME "WNetGetConnectionA"
  42. #else
  43. #define WNETGETCONNECTION_NAME "WNetGetConnectionW"
  44. #define WNETGETUNIVERSALNAME_NAME "WNetGetUniversalNameW"
  45. typedef DWORD (* PFN_WNETGETUNIVERSALNAME)(LPCWSTR szLocalPath, DWORD dwInfoLevel, LPVOID lpBuffer, LPDWORD lpBufferSize);
  46. PFN_WNETGETUNIVERSALNAME pfnWNetGetUniversalName = NULL;
  47. #endif
  48. // Entry Points from GDI32p.DLL
  49. #ifndef _CHICAGO_
  50. HINSTANCE hInstGDI32p = NULL;
  51. typedef HBRUSH (* PFN_GDICONVERTBRUSH)(HBRUSH hbrush);
  52. typedef HBRUSH (* PFN_GDICREATELOCALBRUSH)(HBRUSH hbrushRemote);
  53. PFN_GDICONVERTBRUSH pfnGdiConvertBrush = NULL;
  54. PFN_GDICREATELOCALBRUSH pfnGdiCreateLocalBrush = NULL;
  55. #define GDICONVERTBRUSH_NAME "GdiConvertBrush"
  56. #define GDICREATELOCALBRUSH_NAME "GdiCreateLocalBrush"
  57. #endif
  58. #ifdef _TRACKLINK_
  59. #ifndef _CAIRO_ // !_CAIRO_
  60. #undef DEFINE_GUID
  61. #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
  62. EXTERN_C const GUID CDECL name \
  63. = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
  64. #define DEFINE_SHLGUID(name, l, w1, w2) DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46)
  65. DEFINE_SHLGUID(CLSID_ShellLink, 0x00021401L, 0, 0);
  66. #ifdef _CHICAGO_
  67. DEFINE_SHLGUID(IID_IShellLink, 0x000214EEL, 0, 0);
  68. #else
  69. DEFINE_SHLGUID(IID_IShellLink, 0x000214F9L, 0, 0);
  70. #endif // _CHICAGO_
  71. #undef DEFINE_GUID
  72. #endif // !_CAIRO_
  73. IClassFactory *g_pcfShellLink = NULL;
  74. #endif // _TRACKLINK_
  75. #ifdef _CAIRO_
  76. HINSTANCE hDsys = NULL;
  77. #endif
  78. // Entry Points from SHELL32.DLL
  79. HINSTANCE hInstSHELL32 = NULL;
  80. typedef HICON (* PFN_EXTRACTICON)(HINSTANCE hInst, LPCTSTR szExeName, UINT nIconIndex);
  81. PFN_EXTRACTICON pfnExtractIcon = NULL;
  82. #ifdef _CHICAGO_
  83. #define EXTRACTICON_NAME "ExtractIconA"
  84. #else
  85. #define EXTRACTICON_NAME "ExtractIconW"
  86. #endif
  87. typedef HICON (* PFN_EXTRACTASSOCIATEDICON)(HINSTANCE hInst, LPCTSTR szExeName,
  88. LPWORD pIndex);
  89. PFN_EXTRACTASSOCIATEDICON pfnExtractAssociatedIcon = NULL;
  90. #ifdef _CHICAGO_
  91. #define EXTRACTASSOCIATEDICON_NAME "ExtractAssociatedIconA"
  92. #else
  93. #define EXTRACTASSOCIATEDICON_NAME "ExtractAssociatedIconW"
  94. #endif
  95. typedef DWORD (* PFN_SHGETFILEINFO)(LPCTSTR pszPath, DWORD dwFileAttributes,
  96. SHFILEINFO FAR *psfi, UINT cbFileInfo, UINT uFlags);
  97. PFN_SHGETFILEINFO pfnSHGetFileInfo = NULL;
  98. #ifdef _CHICAGO_
  99. #define SHGETFILEINFO_NAME "SHGetFileInfoA"
  100. #else
  101. #define SHGETFILEINFO_NAME "SHGetFileInfoW"
  102. #endif
  103. // Entry Points from IMAGEHLP.DLL
  104. HINSTANCE hInstIMAGEHLP = NULL;
  105. typedef BOOL (*PFN_SYMINITIALIZE)(HANDLE hProcess, LPSTR UserSearchPath,
  106. BOOL fInvadeProcess);
  107. PFN_SYMINITIALIZE pfnSymInitialize = NULL;
  108. #define SYMINITIALIZE_NAME "SymInitialize"
  109. typedef BOOL (*PFN_SYMCLEANUP)(HANDLE hProcess);
  110. PFN_SYMCLEANUP pfnSymCleanup = NULL;
  111. #define SYMCLEANUP_NAME "SymCleanup"
  112. typedef BOOL (*PFN_SYMGETSYMFROMADDR)(HANDLE hProcess,
  113. DWORD64 dwAddr, PDWORD64 pdwDisplacement, PIMAGEHLP_SYMBOL64 pSym);
  114. PFN_SYMGETSYMFROMADDR pfnSymGetSymFromAddr64 = NULL;
  115. #define SYMGETSYMFROMADDR_NAME "SymGetSymFromAddr64"
  116. typedef BOOL (*PFN_SYMUNDNAME)(PIMAGEHLP_SYMBOL64 sym, LPSTR lpname, DWORD dwmaxLength);
  117. PFN_SYMUNDNAME pfnSymUnDName64 = NULL;
  118. #define SYMUNDNAME_NAME "SymUnDName64"
  119. //+---------------------------------------------------------------------------
  120. //
  121. // Function: LoadSystemProc
  122. //
  123. // Synopsis: Loads the specified DLL if necessary and finds the specified
  124. // entry point.
  125. //
  126. // Returns: 0: the entry point function ptr is valid
  127. // !0: the entry point function ptr is not valid
  128. //
  129. // History: 10-Jan-95 Rickhi Created
  130. //
  131. //----------------------------------------------------------------------------
  132. BOOL LoadSystemProc(LPSTR szDll, LPCSTR szProc,
  133. HINSTANCE *phInst, FARPROC *ppfnProc)
  134. {
  135. if (*phInst == NULL)
  136. {
  137. // Dll not loaded yet, load it now.
  138. if ((*phInst = LoadLibraryA(szDll)) == NULL)
  139. return GetLastError();
  140. }
  141. // load the entry point
  142. if ((*ppfnProc = GetProcAddress(*phInst, szProc)) == NULL)
  143. return GetLastError();
  144. return 0;
  145. }
  146. //+---------------------------------------------------------------------------
  147. //
  148. // Function: FreeSystemDLLs
  149. //
  150. // Synopsis: Frees any system Dlls that we dynamically loaded.
  151. //
  152. // History: 10-Jan-95 Rickhi Created
  153. //
  154. //----------------------------------------------------------------------------
  155. void FreeSystemDLLs()
  156. {
  157. if (hInstMPR)
  158. FreeLibrary(hInstMPR);
  159. if (hInstSHELL32)
  160. FreeLibrary(hInstSHELL32);
  161. #ifndef _CHICAGO_
  162. if (hInstGDI32p)
  163. FreeLibrary(hInstGDI32p);
  164. #endif // _CHICAGO_
  165. #ifdef _CAIRO_
  166. if (hDsys)
  167. FreeLibrary(hDsys);
  168. #endif // _CAIRO_
  169. if(hInstIMAGEHLP != NULL && hInstIMAGEHLP != INVALID_HANDLE_VALUE)
  170. {
  171. FreeLibrary(hInstIMAGEHLP);
  172. }
  173. }
  174. //+---------------------------------------------------------------------------
  175. //
  176. // Function: OleWNetGetConnection
  177. //
  178. // Synopsis: OLE internal implementation of WNetGetConnection
  179. //
  180. // History: 10-Jan-95 Rickhi Created
  181. //
  182. //----------------------------------------------------------------------------
  183. DWORD OleWNetGetConnection(LPCWSTR lpLocalName, LPWSTR lpRemoteName, LPDWORD lpnLength)
  184. {
  185. if (pfnWNetGetConnection == NULL)
  186. {
  187. DWORD rc = LoadSystemProc("MPR.DLL", WNETGETCONNECTION_NAME,
  188. &hInstMPR, (FARPROC *)&pfnWNetGetConnection);
  189. if (rc != 0)
  190. return rc;
  191. }
  192. #ifdef _CHICAGO_
  193. // For Chicago we need to do the Unicode to Ansi conversions.
  194. CHAR szRemote[MAX_PATH];
  195. CHAR szLocal[MAX_PATH];
  196. WideCharToMultiByte (CP_ACP, WC_COMPOSITECHECK, lpLocalName, -1, szLocal, MAX_PATH, NULL, NULL);
  197. DWORD rc = (pfnWNetGetConnection)(szLocal, szRemote, lpnLength);
  198. if (rc == NO_ERROR)
  199. {
  200. MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, szRemote, -1, lpRemoteName, lstrlenA(szRemote)+1);
  201. }
  202. return rc;
  203. #else
  204. return (pfnWNetGetConnection)(lpLocalName, lpRemoteName, lpnLength);
  205. #endif
  206. }
  207. #ifndef _CHICAGO_
  208. //+---------------------------------------------------------------------------
  209. //
  210. // Function: OleWNetGetUniversalName
  211. //
  212. // Synopsis: OLE internal implementation of WNetGetUniversalName
  213. //
  214. // History: 10-Jan-95 Rickhi Created
  215. //
  216. //----------------------------------------------------------------------------
  217. DWORD OleWNetGetUniversalName(LPCWSTR szLocalPath, DWORD dwInfoLevel,
  218. LPVOID lpBuffer, LPDWORD lpBufferSize)
  219. {
  220. if (pfnWNetGetUniversalName == NULL)
  221. {
  222. DWORD rc = LoadSystemProc("MPR.DLL", WNETGETUNIVERSALNAME_NAME,
  223. &hInstMPR, (FARPROC *)&pfnWNetGetUniversalName);
  224. if (rc != 0)
  225. return rc;
  226. }
  227. return (pfnWNetGetUniversalName)(szLocalPath, dwInfoLevel, lpBuffer, lpBufferSize);
  228. }
  229. #endif
  230. #ifndef _CHICAGO_
  231. //+---------------------------------------------------------------------------
  232. //
  233. // Function: OleGdiConvertBrush
  234. //
  235. // Synopsis: OLE internal implementation of GdiConvertBrush
  236. //
  237. // History: 7-Feb-95 GregJen Created
  238. //
  239. //----------------------------------------------------------------------------
  240. HBRUSH OleGdiConvertBrush(HBRUSH hbrush)
  241. {
  242. if (pfnGdiConvertBrush == NULL)
  243. {
  244. DWORD rc = LoadSystemProc("GDI32P.DLL", GDICONVERTBRUSH_NAME,
  245. &hInstGDI32p, (FARPROC *)&pfnGdiConvertBrush);
  246. if (rc != 0)
  247. return NULL;
  248. }
  249. return (pfnGdiConvertBrush)(hbrush);
  250. }
  251. #endif
  252. #ifndef _CHICAGO_
  253. //+---------------------------------------------------------------------------
  254. //
  255. // Function: OleGdiCreateLocalBrush
  256. //
  257. // Synopsis: OLE internal implementation of GdiConvertBrush
  258. //
  259. // History: 7-Feb-95 GregJen Created
  260. //
  261. //----------------------------------------------------------------------------
  262. HBRUSH OleGdiCreateLocalBrush(HBRUSH hbrushRemote)
  263. {
  264. if (pfnGdiCreateLocalBrush == NULL)
  265. {
  266. DWORD rc = LoadSystemProc("GDI32P.DLL", GDICREATELOCALBRUSH_NAME,
  267. &hInstGDI32p, (FARPROC *)&pfnGdiCreateLocalBrush);
  268. if (rc != 0)
  269. return NULL;
  270. }
  271. return (pfnGdiCreateLocalBrush)(hbrushRemote);
  272. }
  273. #endif
  274. //+---------------------------------------------------------------------------
  275. //
  276. // Function: OleExtractIcon
  277. //
  278. // Synopsis: OLE internal implementation of ExtractIcon
  279. //
  280. // History: 10-Jan-95 Rickhi Created
  281. //
  282. //----------------------------------------------------------------------------
  283. HICON OleExtractIcon(HINSTANCE hInst, LPCWSTR wszExeName, UINT nIconIndex)
  284. {
  285. if (pfnExtractIcon == NULL)
  286. {
  287. DWORD rc = LoadSystemProc("SHELL32.DLL", EXTRACTICON_NAME,
  288. &hInstSHELL32, (FARPROC *)&pfnExtractIcon);
  289. if (rc != 0)
  290. return NULL;
  291. }
  292. #ifdef _CHICAGO_
  293. // For Chicago, we need to do the Unicode to Ansi conversion
  294. CHAR szExeName[MAX_PATH];
  295. WideCharToMultiByte (CP_ACP, WC_COMPOSITECHECK, wszExeName, -1, szExeName, MAX_PATH, NULL, NULL);
  296. return (pfnExtractIcon)(hInst, szExeName, nIconIndex);
  297. #else
  298. return (pfnExtractIcon)(hInst, wszExeName, nIconIndex);
  299. #endif
  300. }
  301. //+---------------------------------------------------------------------------
  302. //
  303. // Function: OleExtractAssociatedIcon
  304. //
  305. // Synopsis: OLE internal implementation of ExtractIcon
  306. //
  307. // History: 225-Jan-95 Alexgo Created
  308. //
  309. //----------------------------------------------------------------------------
  310. HICON OleExtractAssociatedIcon(HINSTANCE hInst, LPCWSTR pszFileName,
  311. LPWORD pIndex)
  312. {
  313. if (pfnExtractAssociatedIcon == NULL)
  314. {
  315. DWORD rc = LoadSystemProc("SHELL32.DLL", EXTRACTASSOCIATEDICON_NAME,
  316. &hInstSHELL32,
  317. (FARPROC *)&pfnExtractAssociatedIcon);
  318. if (rc != 0)
  319. return NULL;
  320. }
  321. #ifdef _CHICAGO_
  322. // For Chicago, we need to do the Unicode to Ansi conversion
  323. CHAR szFileName[MAX_PATH];
  324. WideCharToMultiByte (CP_ACP, WC_COMPOSITECHECK, pszFileName, -1, szFileName, MAX_PATH, NULL, NULL);
  325. return (pfnExtractAssociatedIcon)(hInst, szFileName, pIndex);
  326. #else
  327. return (pfnExtractAssociatedIcon)(hInst, pszFileName, pIndex);
  328. #endif
  329. }
  330. //+---------------------------------------------------------------------------
  331. //
  332. // Function: OleSHGetFileInfo
  333. //
  334. // Synopsis: OLE internal implementation of ExtractIcon
  335. //
  336. // History: 02-Feb-95 Scottsk Created
  337. //
  338. //----------------------------------------------------------------------------
  339. DWORD OleSHGetFileInfo(LPCWSTR pszPath, DWORD dwFileAttributes,
  340. SHFILEINFO FAR *psfi, UINT cbFileInfo, UINT uFlags)
  341. {
  342. if (pfnSHGetFileInfo == NULL)
  343. {
  344. DWORD rc = LoadSystemProc("SHELL32.DLL", SHGETFILEINFO_NAME,
  345. &hInstSHELL32,
  346. (FARPROC *)&pfnSHGetFileInfo);
  347. if (rc != 0)
  348. return NULL;
  349. }
  350. // this nested #ifdef is here so that when this functinality is available
  351. // on NT, simply removing the outer #ifdef will do the right thing.
  352. #ifdef _CHICAGO_
  353. // For Chicago, we need to do the Unicode to Ansi conversion
  354. CHAR szPath[MAX_PATH];
  355. WideCharToMultiByte (CP_ACP, WC_COMPOSITECHECK, pszPath, -1, szPath, MAX_PATH, NULL, NULL);
  356. return (pfnSHGetFileInfo)(szPath, dwFileAttributes, psfi, cbFileInfo, uFlags);
  357. #else
  358. return (pfnSHGetFileInfo)(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags);
  359. #endif
  360. }
  361. //+---------------------------------------------------------------------------
  362. //
  363. // Function: OleGetShellLink
  364. //
  365. // Synopsis: Get an instance of the shell's shell link object.
  366. //
  367. //----------------------------------------------------------------------------
  368. #ifdef _TRACKLINK_
  369. VOID * OleGetShellLink()
  370. {
  371. HRESULT hr;
  372. VOID *pShellLink;
  373. if (g_pcfShellLink == NULL)
  374. {
  375. LPFNGETCLASSOBJECT pfn;
  376. DWORD rc = LoadSystemProc("SHELL32.DLL", "DllGetClassObject",
  377. &hInstSHELL32,
  378. (FARPROC *)&pfn);
  379. if (rc != 0)
  380. return NULL;
  381. hr = (*pfn)(CLSID_ShellLink, IID_IClassFactory, (void**)&g_pcfShellLink);
  382. if (hr != S_OK)
  383. {
  384. if (hInstSHELL32)
  385. {
  386. FreeLibrary(hInstSHELL32);
  387. hInstSHELL32 = NULL;
  388. }
  389. return(NULL);
  390. }
  391. }
  392. Win4Assert(g_pcfShellLink != NULL);
  393. hr = g_pcfShellLink->CreateInstance(NULL, IID_IShellLink, &pShellLink);
  394. return(hr == S_OK ? pShellLink : NULL);
  395. }
  396. #endif
  397. //+---------------------------------------------------------------------------
  398. //
  399. // Function: OleSymInitialize
  400. //
  401. // Synopsis: OLE internal implementation of SymInitialize
  402. //
  403. // History: 11-Jul-95 t-stevan Created
  404. //
  405. //----------------------------------------------------------------------------
  406. BOOL OleSymInitialize(HANDLE hProcess, LPSTR UserSearchPath,
  407. BOOL fInvadeProcess)
  408. {
  409. if(hInstIMAGEHLP == (HINSTANCE) -1)
  410. {
  411. // we already tried loading the DLL, give up
  412. return FALSE;
  413. }
  414. if (pfnSymInitialize == NULL)
  415. {
  416. DWORD rc;
  417. rc = LoadSystemProc("IMAGEHLP.DLL", SYMINITIALIZE_NAME,
  418. &hInstIMAGEHLP, (FARPROC *)&pfnSymInitialize);
  419. if (rc != 0)
  420. {
  421. hInstIMAGEHLP = (HINSTANCE) -1;
  422. return FALSE;
  423. }
  424. }
  425. return (pfnSymInitialize)(hProcess, UserSearchPath, fInvadeProcess);
  426. }
  427. //+---------------------------------------------------------------------------
  428. //
  429. // Function: OleSymCleanup
  430. //
  431. // Synopsis: OLE internal implementation of SymCleanup
  432. //
  433. // History: 11-Jul-95 t-stevan Created
  434. //
  435. //----------------------------------------------------------------------------
  436. BOOL OleSymCleanup(HANDLE hProcess)
  437. {
  438. if(hInstIMAGEHLP == (HINSTANCE) -1)
  439. {
  440. // we already tried loading the DLL, give up
  441. return FALSE;
  442. }
  443. if (pfnSymCleanup == NULL)
  444. {
  445. DWORD rc;
  446. rc = LoadSystemProc("IMAGEHLP.DLL", SYMCLEANUP_NAME,
  447. &hInstIMAGEHLP, (FARPROC *)&pfnSymCleanup);
  448. if (rc != 0)
  449. {
  450. hInstIMAGEHLP = (HINSTANCE) -1;
  451. return FALSE;
  452. }
  453. }
  454. return (pfnSymCleanup)(hProcess);
  455. }
  456. //+---------------------------------------------------------------------------
  457. //
  458. // Function: OleSymGetSymFromAddr
  459. //
  460. // Synopsis: OLE internal implementation of SymGetSymFromAddr
  461. //
  462. // History: 11-Jul-95 t-stevan Created
  463. //
  464. //----------------------------------------------------------------------------
  465. BOOL OleSymGetSymFromAddr(HANDLE hProcess, DWORD64 dwAddr, PDWORD64 pdwDisplacement, PIMAGEHLP_SYMBOL64 pSym)
  466. {
  467. if(hInstIMAGEHLP == (HINSTANCE) -1)
  468. {
  469. // we already tried loading the DLL, give up
  470. return NULL;
  471. }
  472. if (pfnSymGetSymFromAddr64 == NULL)
  473. {
  474. DWORD rc;
  475. rc = LoadSystemProc("IMAGEHLP.DLL", SYMGETSYMFROMADDR_NAME,
  476. &hInstIMAGEHLP, (FARPROC *)&pfnSymGetSymFromAddr64);
  477. if (rc != 0)
  478. {
  479. hInstIMAGEHLP = (HINSTANCE) -1;
  480. return NULL;
  481. }
  482. }
  483. return (pfnSymGetSymFromAddr64)(hProcess, dwAddr, pdwDisplacement, pSym);
  484. }
  485. //+---------------------------------------------------------------------------
  486. //
  487. // Function: OleSymUnDName
  488. //
  489. // Synopsis: OLE internal implementation of SymUnDName
  490. //
  491. // History: 11-Jul-95 t-stevan Created
  492. //
  493. //----------------------------------------------------------------------------
  494. BOOL OleSymUnDName(PIMAGEHLP_SYMBOL64 pSym, LPSTR lpname, DWORD dwmaxLength)
  495. {
  496. if(hInstIMAGEHLP == (HINSTANCE) -1)
  497. {
  498. // we already tried loading the DLL, give up
  499. return FALSE;
  500. }
  501. if (pfnSymUnDName64 == NULL)
  502. {
  503. DWORD rc;
  504. rc = LoadSystemProc("IMAGEHLP.DLL", SYMUNDNAME_NAME,
  505. &hInstIMAGEHLP, (FARPROC *)&pfnSymUnDName64);
  506. if (rc != 0)
  507. {
  508. hInstIMAGEHLP = (HINSTANCE) -1;
  509. return FALSE;
  510. }
  511. }
  512. return (pfnSymUnDName64)(pSym, lpname, dwmaxLength);
  513. }
  514. #ifdef _CAIRO_
  515. //+---------------------------------------------------------------------------
  516. //
  517. // Function: GetHandleServerInfo, public
  518. //
  519. // Synopsis: Wrapper for DfsGetHandleServerInfo
  520. //
  521. // Arguments: same as DfsGetHandleServerInfo
  522. //
  523. // Returns: Appropriate status code
  524. //
  525. // History: 06-Nov-95 Henrylee created
  526. //
  527. //----------------------------------------------------------------------------
  528. STDAPI GetHandleServerInfo(
  529. IN HANDLE hFile,
  530. IN OUT LPWSTR lpServerName,
  531. IN OUT LPDWORD lpcbServerName,
  532. IN OUT LPWSTR lpReplSpecificPath,
  533. IN OUT LPDWORD lpcbReplSpecificPath)
  534. {
  535. static (*pDfsGetHandleServerInfo) (HANDLE,
  536. LPWSTR, LPDWORD, LPWSTR, LPDWORD) = NULL;
  537. if (hDsys == NULL || pDfsGetHandleServerInfo == NULL)
  538. {
  539. DWORD dw = LoadSystemProc ("DSYS.DLL", "DfsGetHandleServerInfo",
  540. &hDsys, (FARPROC *) &pDfsGetHandleServerInfo);
  541. if (dw != ERROR_SUCCESS)
  542. {
  543. return HRESULT_FROM_WIN32 (dw);
  544. }
  545. }
  546. return (*pDfsGetHandleServerInfo) (hFile,
  547. lpServerName,
  548. lpcbServerName,
  549. lpReplSpecificPath,
  550. lpcbReplSpecificPath);
  551. }
  552. #endif // _CAIRO_