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.

604 lines
12 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. util.cpp
  5. Abstract:
  6. This module contains utility routines for the fax transport provider.
  7. Author:
  8. Wesley Witt (wesw) 13-Aug-1996
  9. Revision History:
  10. 20/10/99 -danl-
  11. Fix GetServerName as GetServerNameFromPrinterName.
  12. dd-mm-yy -author-
  13. description
  14. --*/
  15. #include "faxxp.h"
  16. #include "debugex.h"
  17. #pragma hdrstop
  18. //
  19. // globals
  20. //
  21. BOOL oleInitialized;
  22. LPVOID
  23. MapiMemAlloc(
  24. SIZE_T Size
  25. )
  26. /*++
  27. Routine Description:
  28. Memory allocator.
  29. Arguments:
  30. Size - Number of bytes to allocate.
  31. Return Value:
  32. Pointer to the allocated memory or NULL for failure.
  33. --*/
  34. {
  35. LPVOID ptr=NULL;
  36. HRESULT hResult;
  37. // [Win64bug] gpfnAllocateBuffer should accpet size_t as allocating size
  38. hResult = gpfnAllocateBuffer( DWORD(Size), &ptr );
  39. if (S_OK == hResult)
  40. {
  41. ZeroMemory( ptr, Size );
  42. }
  43. return ptr;
  44. }
  45. LPVOID
  46. MapiMemReAlloc(
  47. LPVOID ptr,
  48. SIZE_T Size
  49. )
  50. /*++
  51. Routine Description:
  52. Memory re-allocator.
  53. Arguments:
  54. ptr - pre-allocated buffer
  55. Size - Number of bytes to allocate.
  56. Return Value:
  57. Pointer to the allocated memory or NULL for failure.
  58. --*/
  59. {
  60. LPVOID NewPtr = NULL;
  61. HRESULT hResult;
  62. // [Win64bug] gpfnAllocateBuffer should accpet size_t as allocating size
  63. hResult = gpfnAllocateMore( DWORD(Size), ptr, &NewPtr );
  64. if (S_OK == hResult)
  65. {
  66. ZeroMemory( NewPtr, Size );
  67. }
  68. return NewPtr;
  69. }
  70. VOID
  71. MapiMemFree(
  72. LPVOID ptr
  73. )
  74. /*++
  75. Routine Description:
  76. Memory de-allocator.
  77. Arguments:
  78. ptr - Pointer to the memory block.
  79. Return Value:
  80. None.
  81. --*/
  82. {
  83. if (ptr)
  84. {
  85. gpfnFreeBuffer( ptr );
  86. }
  87. }
  88. PVOID
  89. MyEnumPrinters(
  90. LPTSTR pServerName,
  91. DWORD level,
  92. OUT PDWORD pcPrinters
  93. )
  94. /*++
  95. Routine Description:
  96. Wrapper function for spooler API EnumPrinters
  97. Arguments:
  98. pServerName - Specifies the name of the print server
  99. level - Level of PRINTER_INFO_x structure
  100. pcPrinters - Returns the number of printers enumerated
  101. Return Value:
  102. Pointer to an array of PRINTER_INFO_x structures
  103. NULL if there is an error
  104. --*/
  105. {
  106. DBG_ENTER(TEXT("MyEnumPrinters"));
  107. PBYTE pPrinterInfo = NULL;
  108. DWORD cb;
  109. // first, we give no printer information buffer, so the function fails, but returns
  110. // in cb the number of bytes needed. then we allocate enough memory,
  111. // and call the function again, this time with all of the needed parameters.
  112. if (! EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
  113. pServerName,
  114. level,
  115. NULL,
  116. 0,
  117. &cb,
  118. pcPrinters) //the call failed
  119. && (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) //this is the reason for failing
  120. && (pPrinterInfo = (PBYTE)MemAlloc(cb)) //we managed to allocate more memory
  121. && EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
  122. pServerName,
  123. level,
  124. pPrinterInfo,
  125. cb,
  126. &cb,
  127. pcPrinters)) //and now the call succeded
  128. {
  129. return pPrinterInfo;
  130. }
  131. MemFree(pPrinterInfo);
  132. return NULL;
  133. }
  134. HRESULT WINAPI
  135. OpenServiceProfileSection(
  136. LPMAPISUP pSupObj,
  137. LPPROFSECT * ppProfSectObj
  138. )
  139. /*++
  140. Routine Description:
  141. This function opens the profile section of this service, where the
  142. properties of a FAX provider (AB, MS, or XP) are stored.
  143. Arguments:
  144. pSupObj - Pointer to the provider support object
  145. ppProfSectObj - Where we return a pointer to the service profile
  146. section of the provider
  147. Return Value:
  148. An HRESULT.
  149. --*/
  150. {
  151. HRESULT hResult;
  152. DBG_ENTER(TEXT("OpenServiceProfileSection"),hResult);
  153. SPropTagArray sptService = { 1, { PR_SERVICE_UID } };
  154. LPPROFSECT pProvProfSectObj;
  155. ULONG cValues;
  156. LPSPropValue pProp;
  157. //
  158. // Get the PROVIDER profile section
  159. //
  160. hResult = pSupObj->OpenProfileSection(
  161. NULL,
  162. MAPI_MODIFY,
  163. &pProvProfSectObj
  164. );
  165. if (SUCCEEDED(hResult))
  166. {
  167. // Get the UID of the profile section of the service where this provider is installed
  168. hResult = pProvProfSectObj->GetProps (&sptService, FALSE, &cValues, &pProp);
  169. if (SUCCEEDED(hResult))
  170. {
  171. if (S_OK == hResult)
  172. {
  173. // Now, with the obtained UID, open the profile section of the service
  174. hResult = pSupObj->OpenProfileSection ((LPMAPIUID)pProp->Value.bin.lpb,
  175. MAPI_MODIFY,
  176. ppProfSectObj);
  177. }
  178. else
  179. {
  180. hResult = E_FAIL;
  181. }
  182. MemFree( pProp );
  183. }
  184. pProvProfSectObj->Release();
  185. }
  186. return hResult;
  187. }
  188. LPTSTR
  189. RemoveLastNode(
  190. LPTSTR Path
  191. )
  192. /*++
  193. Routine Description:
  194. Removes the last node from a path string.
  195. Arguments:
  196. Path - Path string.
  197. Return Value:
  198. Pointer to the path string.
  199. --*/
  200. {
  201. LPTSTR Pstr = NULL;
  202. if (Path == NULL || Path[0] == 0)
  203. {
  204. return Path;
  205. }
  206. Pstr = _tcsrchr(Path,TEXT('\\'));
  207. if( Pstr && (*_tcsinc(Pstr)) == '\0' )
  208. {
  209. // the last character is a backslash, truncate it...
  210. _tcsset(Pstr,TEXT('\0'));
  211. Pstr = _tcsdec(Path,Pstr);
  212. }
  213. Pstr = _tcsrchr(Path,TEXT('\\'));
  214. if( Pstr )
  215. {
  216. _tcsnset(_tcsinc(Pstr),TEXT('\0'),1);
  217. }
  218. return Path;
  219. }
  220. PDEVMODE
  221. GetPerUserDevmode(
  222. LPTSTR PrinterName
  223. )
  224. {
  225. PDEVMODE DevMode = NULL;
  226. LONG Size;
  227. PRINTER_DEFAULTS PrinterDefaults;
  228. HANDLE hPrinter;
  229. PrinterDefaults.pDatatype = NULL;
  230. PrinterDefaults.pDevMode = NULL;
  231. PrinterDefaults.DesiredAccess = PRINTER_READ;
  232. if (!OpenPrinter( PrinterName, &hPrinter, &PrinterDefaults ))
  233. {
  234. DebugPrint(( TEXT("OpenPrinter() failed, ec=%d"), ::GetLastError() ));
  235. return NULL;
  236. }
  237. Size = DocumentProperties(
  238. NULL,
  239. hPrinter,
  240. PrinterName,
  241. NULL,
  242. NULL,
  243. 0
  244. );
  245. if (Size < 0)
  246. {
  247. goto exit;
  248. }
  249. DevMode = (PDEVMODE) MemAlloc( Size );
  250. if (DevMode == NULL)
  251. {
  252. goto exit;
  253. }
  254. Size = DocumentProperties(
  255. NULL,
  256. hPrinter,
  257. PrinterName,
  258. DevMode,
  259. NULL,
  260. DM_OUT_BUFFER
  261. );
  262. if (Size < 0)
  263. {
  264. MemFree( DevMode );
  265. DevMode = NULL;
  266. goto exit;
  267. }
  268. exit:
  269. ClosePrinter( hPrinter );
  270. return DevMode;
  271. }
  272. DWORD
  273. GetDwordProperty(
  274. LPSPropValue pProps,
  275. DWORD PropId
  276. )
  277. {
  278. if (PROP_TYPE(pProps[PropId].ulPropTag) == PT_ERROR)
  279. {
  280. return 0;
  281. }
  282. return pProps[PropId].Value.ul;
  283. }
  284. DWORD
  285. GetBinaryProperty(
  286. LPSPropValue pProps,
  287. DWORD PropId,
  288. OUT LPVOID Buffer,
  289. DWORD SizeOfBuffer
  290. )
  291. {
  292. if (PROP_TYPE(pProps[PropId].ulPropTag) == PT_ERROR)
  293. {
  294. return 0;
  295. }
  296. if (pProps[PropId].Value.bin.cb > SizeOfBuffer)
  297. {
  298. return 0;
  299. }
  300. CopyMemory( Buffer, pProps[PropId].Value.bin.lpb, pProps[PropId].Value.bin.cb );
  301. return pProps[PropId].Value.bin.cb;
  302. }
  303. PVOID
  304. MyGetPrinter(
  305. LPTSTR PrinterName,
  306. DWORD level
  307. )
  308. /*++
  309. Routine Description:
  310. Wrapper function for GetPrinter spooler API
  311. Arguments:
  312. hPrinter - Identifies the printer in question
  313. level - Specifies the level of PRINTER_INFO_x structure requested
  314. Return Value:
  315. Pointer to a PRINTER_INFO_x structure, NULL if there is an error
  316. --*/
  317. {
  318. DBG_ENTER(TEXT("MyGetPrinter"));
  319. HANDLE hPrinter;
  320. PBYTE pPrinterInfo = NULL;
  321. DWORD cbNeeded;
  322. PRINTER_DEFAULTS PrinterDefaults;
  323. PrinterDefaults.pDatatype = NULL;
  324. PrinterDefaults.pDevMode = NULL;
  325. PrinterDefaults.DesiredAccess = PRINTER_READ; //PRINTER_ALL_ACCESS;
  326. if (!OpenPrinter( PrinterName, &hPrinter, &PrinterDefaults ))
  327. {
  328. CALL_FAIL (GENERAL_ERR, TEXT("OpenPrinter"), ::GetLastError());
  329. return NULL;
  330. }
  331. if (!GetPrinter( hPrinter, level, NULL, 0, &cbNeeded ) &&
  332. ::GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
  333. (pPrinterInfo = (PBYTE) MemAlloc( cbNeeded )) &&
  334. GetPrinter( hPrinter, level, pPrinterInfo, cbNeeded, &cbNeeded ))
  335. {
  336. ClosePrinter( hPrinter );
  337. return pPrinterInfo;
  338. }
  339. ClosePrinter( hPrinter );
  340. MemFree( pPrinterInfo );
  341. return NULL;
  342. }
  343. BOOL
  344. GetServerNameFromPrinterName(
  345. LPTSTR lptszPrinterName,
  346. LPTSTR *pptszServerName
  347. )
  348. /*++
  349. Routine Description:
  350. retrieve the server name given a printer name
  351. Arguments:
  352. [in] lptszPrinterName - Identifies the printer in question
  353. [out] lptszServerName - Address of pointer to output string buffer.
  354. NULL indicates local server.
  355. The caller is responsible to free the buffer which
  356. pointer is given in this parameter.
  357. Return Value:
  358. BOOL: TRUE - operation succeeded , FALSE: failed
  359. --*/
  360. {
  361. BOOL bRes = FALSE;
  362. DBG_ENTER(TEXT("GetServerNameFromPrinterName"),bRes);
  363. PPRINTER_INFO_2 ppi2 = NULL;
  364. LPTSTR lptstrBuffer = NULL;
  365. if (lptszPrinterName)
  366. {
  367. if (ppi2 = (PPRINTER_INFO_2) MyGetPrinter(lptszPrinterName,2))
  368. {
  369. bRes = GetServerNameFromPrinterInfo(ppi2,&lptstrBuffer);
  370. MemFree(ppi2);
  371. if (bRes)
  372. {
  373. *pptszServerName = lptstrBuffer;
  374. }
  375. }
  376. }
  377. return bRes;
  378. }
  379. LPTSTR
  380. ConvertAStringToTString(LPCSTR lpcstrSource)
  381. {
  382. LPTSTR lptstrDestination;
  383. if (!lpcstrSource)
  384. return NULL;
  385. #ifdef UNICODE
  386. lptstrDestination = AnsiStringToUnicodeString( lpcstrSource );
  387. #else // !UNICODE
  388. lptstrDestination = StringDup( lpcstrSource );
  389. #endif // UNICODE
  390. return lptstrDestination;
  391. }
  392. LPSTR
  393. ConvertTStringToAString(LPCTSTR lpctstrSource)
  394. {
  395. LPSTR lpstrDestination;
  396. if (!lpctstrSource)
  397. return NULL;
  398. #ifdef UNICODE
  399. lpstrDestination = UnicodeStringToAnsiString( lpctstrSource );
  400. #else // !UNICODE
  401. lpstrDestination = StringDup( lpctstrSource );
  402. #endif // UNICODE
  403. return lpstrDestination;
  404. }
  405. void
  406. ErrorMsgBox(
  407. HINSTANCE hInstance,
  408. DWORD dwMsgId
  409. )
  410. /*++
  411. Routine Description:
  412. Display error message box
  413. Arguments:
  414. hInstance - [in] resource instance handle
  415. dwMsgId - [in] string resource ID
  416. Return Value:
  417. none
  418. --*/
  419. {
  420. TCHAR* ptCaption=NULL;
  421. TCHAR tszCaption[MAX_PATH];
  422. TCHAR tszMessage[MAX_PATH];
  423. DBG_ENTER(TEXT("ErrorMsgBox"));
  424. if(!LoadString( hInstance, IDS_FAX_MESSAGE, tszCaption, sizeof(tszCaption) / sizeof(tszCaption[0])))
  425. {
  426. CALL_FAIL(GENERAL_ERR, TEXT("LoadString"), ::GetLastError());
  427. }
  428. else
  429. {
  430. ptCaption = tszCaption;
  431. }
  432. if(!LoadString( hInstance, dwMsgId, tszMessage, sizeof(tszMessage) / sizeof(tszMessage[0])))
  433. {
  434. CALL_FAIL(GENERAL_ERR, TEXT("LoadString"), ::GetLastError());
  435. Assert(FALSE);
  436. return;
  437. }
  438. MessageBeep(MB_ICONEXCLAMATION);
  439. AlignedMessageBox(NULL, tszMessage, ptCaption, MB_OK | MB_ICONERROR);
  440. }