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.

1678 lines
68 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. printers.c
  5. Abstract:
  6. <abstract>
  7. Author:
  8. Calin Negreanu (calinn) 08 Mar 2000
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. //
  13. // Includes
  14. //
  15. #include "pch.h"
  16. #include "logmsg.h"
  17. #include <winspool.h>
  18. #define DBG_PRINTERS "Printers"
  19. //
  20. // Strings
  21. //
  22. #define S_PRINTERS_POOL_NAME "Printers"
  23. #define S_PRINTERS_NAME TEXT("Printers")
  24. #define S_CORPNET_NAME TEXT("Net Printers and Drives")
  25. //
  26. // Constants
  27. //
  28. // None
  29. //
  30. // Macros
  31. //
  32. // None
  33. //
  34. // Types
  35. //
  36. typedef struct {
  37. PCTSTR Pattern;
  38. HASHTABLE_ENUM HashData;
  39. } PRINTER_ENUM, *PPRINTER_ENUM;
  40. typedef struct {
  41. BOOL Default;
  42. DWORD dmFields;
  43. SHORT dmOrientation;
  44. SHORT dmPaperSize;
  45. SHORT dmPaperLength;
  46. SHORT dmPaperWidth;
  47. POINTL dmPosition;
  48. SHORT dmScale;
  49. SHORT dmCopies;
  50. SHORT dmDefaultSource;
  51. SHORT dmPrintQuality;
  52. SHORT dmColor;
  53. SHORT dmDuplex;
  54. SHORT dmYResolution;
  55. SHORT dmTTOption;
  56. SHORT dmCollate;
  57. CHAR dmFormName[CCHFORMNAME];
  58. WORD dmLogPixels;
  59. DWORD dmBitsPerPel;
  60. DWORD dmPelsWidth;
  61. DWORD dmPelsHeight;
  62. DWORD dmDisplayFlags;
  63. DWORD dmNup;
  64. DWORD dmDisplayFrequency;
  65. DWORD dmICMMethod;
  66. DWORD dmICMIntent;
  67. DWORD dmMediaType;
  68. DWORD dmDitherType;
  69. DWORD dmPanningWidth;
  70. DWORD dmPanningHeight;
  71. } PRINTER_DATAA, *PPRINTER_DATAA;
  72. typedef struct {
  73. BOOL Default;
  74. DWORD dmFields;
  75. SHORT dmOrientation;
  76. SHORT dmPaperSize;
  77. SHORT dmPaperLength;
  78. SHORT dmPaperWidth;
  79. POINTL dmPosition;
  80. SHORT dmScale;
  81. SHORT dmCopies;
  82. SHORT dmDefaultSource;
  83. SHORT dmPrintQuality;
  84. SHORT dmColor;
  85. SHORT dmDuplex;
  86. SHORT dmYResolution;
  87. SHORT dmTTOption;
  88. SHORT dmCollate;
  89. WCHAR dmFormName[CCHFORMNAME];
  90. WORD dmLogPixels;
  91. DWORD dmBitsPerPel;
  92. DWORD dmPelsWidth;
  93. DWORD dmPelsHeight;
  94. DWORD dmDisplayFlags;
  95. DWORD dmNup;
  96. DWORD dmDisplayFrequency;
  97. DWORD dmICMMethod;
  98. DWORD dmICMIntent;
  99. DWORD dmMediaType;
  100. DWORD dmDitherType;
  101. DWORD dmPanningWidth;
  102. DWORD dmPanningHeight;
  103. } PRINTER_DATAW, *PPRINTER_DATAW;
  104. #ifdef UNICODE
  105. #define PRINTER_DATA PRINTER_DATAW
  106. #define PPRINTER_DATA PPRINTER_DATAW
  107. #else
  108. #define PRINTER_DATA PRINTER_DATAA
  109. #define PPRINTER_DATA PPRINTER_DATAA
  110. #endif
  111. //
  112. // Globals
  113. //
  114. BOOL g_PrinterMigEnabled = FALSE;
  115. PMHANDLE g_PrintersPool = NULL;
  116. HASHTABLE g_PrintersTable;
  117. MIG_OBJECTTYPEID g_PrinterTypeId = 0;
  118. static BOOL g_IsWin9x = FALSE;
  119. GROWBUFFER g_PrinterConversionBuff = INIT_GROWBUFFER;
  120. BOOL g_DelayPrintersOp = FALSE;
  121. //
  122. // Macro expansion list
  123. //
  124. // None
  125. //
  126. // Private function prototypes
  127. //
  128. // None
  129. //
  130. // Macro expansion definition
  131. //
  132. // None
  133. //
  134. // Private prototypes
  135. //
  136. SGMENUMERATIONCALLBACK SgmPrintersCallback;
  137. VCMENUMERATIONCALLBACK VcmPrintersCallback;
  138. TYPE_ENUMFIRSTPHYSICALOBJECT EnumFirstPrinter;
  139. TYPE_ENUMNEXTPHYSICALOBJECT EnumNextPrinter;
  140. TYPE_ABORTENUMPHYSICALOBJECT AbortEnumPrinter;
  141. TYPE_CONVERTOBJECTTOMULTISZ ConvertPrinterToMultiSz;
  142. TYPE_CONVERTMULTISZTOOBJECT ConvertMultiSzToPrinter;
  143. TYPE_GETNATIVEOBJECTNAME GetNativePrinterName;
  144. TYPE_ACQUIREPHYSICALOBJECT AcquirePrinter;
  145. TYPE_RELEASEPHYSICALOBJECT ReleasePrinter;
  146. TYPE_DOESPHYSICALOBJECTEXIST DoesPrinterExist;
  147. TYPE_REMOVEPHYSICALOBJECT RemovePrinter;
  148. TYPE_CREATEPHYSICALOBJECT CreatePrinter;
  149. TYPE_REPLACEPHYSICALOBJECT ReplacePrinter;
  150. TYPE_CONVERTOBJECTCONTENTTOUNICODE ConvertPrinterContentToUnicode;
  151. TYPE_CONVERTOBJECTCONTENTTOANSI ConvertPrinterContentToAnsi;
  152. TYPE_FREECONVERTEDOBJECTCONTENT FreeConvertedPrinterContent;
  153. //
  154. // Code
  155. //
  156. BOOL
  157. PrintersInitialize (
  158. VOID
  159. )
  160. {
  161. OSVERSIONINFO versionInfo;
  162. ZeroMemory (&versionInfo, sizeof (OSVERSIONINFO));
  163. versionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
  164. if (!GetVersionEx (&versionInfo)) {
  165. return FALSE;
  166. }
  167. g_IsWin9x = (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
  168. g_PrintersTable = HtAllocWithData (sizeof (PPRINTER_DATA));
  169. if (!g_PrintersTable) {
  170. return FALSE;
  171. }
  172. g_PrintersPool = PmCreateNamedPool (S_PRINTERS_POOL_NAME);
  173. return (g_PrintersPool != NULL);
  174. }
  175. BOOL
  176. pLoadPrintersData (
  177. VOID
  178. )
  179. {
  180. PTSTR defaultPrinter = NULL;
  181. PTSTR defaultPrinterPtr = NULL;
  182. DWORD defaultGap = 1024;
  183. DWORD initialSize = 0;
  184. DWORD resultSize = 0;
  185. PBYTE prnBuffer = NULL;
  186. DWORD prnBufferSize = 0;
  187. DWORD prnNumbers = 0;
  188. DWORD error;
  189. PPRINTER_INFO_2 prnInfo;
  190. PPRINTER_DATA printerData;
  191. do {
  192. initialSize = initialSize + defaultGap;
  193. defaultPrinter = (PTSTR) PmGetMemory (g_PrintersPool, initialSize * sizeof (TCHAR));
  194. resultSize = GetProfileString (TEXT("windows"), TEXT("device"), TEXT(",,"), defaultPrinter, initialSize);
  195. if (resultSize < (initialSize - 1)) {
  196. break;
  197. }
  198. PmReleaseMemory (g_PrintersPool, defaultPrinter);
  199. } while (TRUE);
  200. defaultPrinterPtr = _tcschr (defaultPrinter, TEXT(','));
  201. if (defaultPrinterPtr) {
  202. *defaultPrinterPtr = 0;
  203. }
  204. if (!EnumPrinters (PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, NULL, 0, &prnBufferSize, &prnNumbers)) {
  205. error = GetLastError ();
  206. if (error != ERROR_INSUFFICIENT_BUFFER) {
  207. PmReleaseMemory (g_PrintersPool, defaultPrinter);
  208. return FALSE;
  209. }
  210. }
  211. if (prnBufferSize) {
  212. prnBuffer = PmGetMemory (g_PrintersPool, prnBufferSize);
  213. if (!EnumPrinters (PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, prnBuffer, prnBufferSize, &prnBufferSize, &prnNumbers)) {
  214. PmReleaseMemory (g_PrintersPool, defaultPrinter);
  215. PmReleaseMemory (g_PrintersPool, prnBuffer);
  216. return FALSE;
  217. }
  218. prnInfo = (PPRINTER_INFO_2) (prnBuffer);
  219. while (prnNumbers) {
  220. if (prnInfo->Attributes & PRINTER_ATTRIBUTE_NETWORK) {
  221. printerData = (PPRINTER_DATA) PmGetMemory (g_PrintersPool, sizeof (PRINTER_DATA));
  222. ZeroMemory (printerData, sizeof (PRINTER_DATA));
  223. if (prnInfo->pDevMode) {
  224. // let's save printer settings
  225. printerData->dmFields = prnInfo->pDevMode->dmFields;
  226. if (prnInfo->pDevMode->dmFields & DM_ORIENTATION) {
  227. printerData->dmOrientation = prnInfo->pDevMode->dmOrientation;
  228. }
  229. if (prnInfo->pDevMode->dmFields & DM_PAPERSIZE) {
  230. printerData->dmPaperSize = prnInfo->pDevMode->dmPaperSize;
  231. }
  232. if (prnInfo->pDevMode->dmFields & DM_PAPERLENGTH) {
  233. printerData->dmPaperLength = prnInfo->pDevMode->dmPaperLength;
  234. }
  235. if (prnInfo->pDevMode->dmFields & DM_PAPERWIDTH) {
  236. printerData->dmPaperWidth = prnInfo->pDevMode->dmPaperWidth;
  237. }
  238. if (prnInfo->pDevMode->dmFields & DM_SCALE) {
  239. printerData->dmScale = prnInfo->pDevMode->dmScale;
  240. }
  241. if (prnInfo->pDevMode->dmFields & DM_POSITION) {
  242. CopyMemory (&printerData->dmPosition, &prnInfo->pDevMode->dmPosition, sizeof(POINTL));
  243. }
  244. if (prnInfo->pDevMode->dmFields & DM_NUP) {
  245. printerData->dmNup = prnInfo->pDevMode->dmNup;
  246. }
  247. if (prnInfo->pDevMode->dmFields & DM_COPIES) {
  248. printerData->dmCopies = prnInfo->pDevMode->dmCopies;
  249. }
  250. if (prnInfo->pDevMode->dmFields & DM_DEFAULTSOURCE) {
  251. printerData->dmDefaultSource = prnInfo->pDevMode->dmDefaultSource;
  252. }
  253. if (prnInfo->pDevMode->dmFields & DM_PRINTQUALITY) {
  254. printerData->dmPrintQuality = prnInfo->pDevMode->dmPrintQuality;
  255. }
  256. if (prnInfo->pDevMode->dmFields & DM_COLOR) {
  257. printerData->dmColor = prnInfo->pDevMode->dmColor;
  258. }
  259. if (prnInfo->pDevMode->dmFields & DM_DUPLEX) {
  260. printerData->dmDuplex = prnInfo->pDevMode->dmDuplex;
  261. }
  262. if (prnInfo->pDevMode->dmFields & DM_YRESOLUTION) {
  263. printerData->dmYResolution = prnInfo->pDevMode->dmYResolution;
  264. }
  265. if (prnInfo->pDevMode->dmFields & DM_TTOPTION) {
  266. printerData->dmTTOption = prnInfo->pDevMode->dmTTOption;
  267. }
  268. if (prnInfo->pDevMode->dmFields & DM_COLLATE) {
  269. printerData->dmCollate = prnInfo->pDevMode->dmCollate;
  270. }
  271. if (prnInfo->pDevMode->dmFields & DM_FORMNAME) {
  272. CopyMemory (printerData->dmFormName, prnInfo->pDevMode->dmFormName, sizeof (printerData->dmFormName));
  273. }
  274. if (prnInfo->pDevMode->dmFields & DM_LOGPIXELS) {
  275. printerData->dmLogPixels = prnInfo->pDevMode->dmLogPixels;
  276. }
  277. if (prnInfo->pDevMode->dmFields & DM_BITSPERPEL) {
  278. printerData->dmBitsPerPel = prnInfo->pDevMode->dmBitsPerPel;
  279. }
  280. if (prnInfo->pDevMode->dmFields & DM_PELSWIDTH) {
  281. printerData->dmPelsWidth = prnInfo->pDevMode->dmPelsWidth;
  282. }
  283. if (prnInfo->pDevMode->dmFields & DM_PELSHEIGHT) {
  284. printerData->dmPelsHeight = prnInfo->pDevMode->dmPelsHeight;
  285. }
  286. if (prnInfo->pDevMode->dmFields & DM_DISPLAYFLAGS) {
  287. printerData->dmDisplayFlags = prnInfo->pDevMode->dmDisplayFlags;
  288. }
  289. if (prnInfo->pDevMode->dmFields & DM_DISPLAYFREQUENCY) {
  290. printerData->dmDisplayFrequency = prnInfo->pDevMode->dmDisplayFrequency;
  291. }
  292. if (prnInfo->pDevMode->dmFields & DM_ICMMETHOD) {
  293. printerData->dmICMMethod = prnInfo->pDevMode->dmICMMethod;
  294. }
  295. if (prnInfo->pDevMode->dmFields & DM_ICMINTENT) {
  296. printerData->dmICMIntent = prnInfo->pDevMode->dmICMIntent;
  297. }
  298. if (prnInfo->pDevMode->dmFields & DM_MEDIATYPE) {
  299. printerData->dmMediaType = prnInfo->pDevMode->dmMediaType;
  300. }
  301. if (prnInfo->pDevMode->dmFields & DM_DITHERTYPE) {
  302. printerData->dmDitherType = prnInfo->pDevMode->dmDitherType;
  303. }
  304. if (prnInfo->pDevMode->dmFields & DM_PANNINGWIDTH) {
  305. printerData->dmPanningWidth = prnInfo->pDevMode->dmPanningWidth;
  306. }
  307. if (prnInfo->pDevMode->dmFields & DM_PANNINGHEIGHT) {
  308. printerData->dmPanningHeight = prnInfo->pDevMode->dmPanningHeight;
  309. }
  310. }
  311. printerData->Default = StringIMatch (prnInfo->pPrinterName, defaultPrinter);
  312. if (g_IsWin9x) {
  313. HtAddStringEx (g_PrintersTable, prnInfo->pPortName, &printerData, FALSE);
  314. } else {
  315. HtAddStringEx (g_PrintersTable, prnInfo->pPrinterName, &printerData, FALSE);
  316. }
  317. }
  318. prnInfo ++;
  319. prnNumbers --;
  320. }
  321. PmReleaseMemory (g_PrintersPool, prnBuffer);
  322. }
  323. PmReleaseMemory (g_PrintersPool, defaultPrinter);
  324. return TRUE;
  325. }
  326. VOID
  327. PrintersTerminate (
  328. VOID
  329. )
  330. {
  331. HASHTABLE_ENUM e;
  332. PPRINTER_DATA printerData;
  333. GbFree (&g_PrinterConversionBuff);
  334. if (g_PrintersTable) {
  335. if (EnumFirstHashTableString (&e, g_PrintersTable)) {
  336. do {
  337. printerData = *((PPRINTER_DATA *) e.ExtraData);
  338. if (printerData) {
  339. PmReleaseMemory (g_PrintersPool, printerData);
  340. }
  341. } while (EnumNextHashTableString (&e));
  342. }
  343. HtFree (g_PrintersTable);
  344. g_PrintersTable = NULL;
  345. }
  346. if (g_PrintersPool) {
  347. PmDestroyPool (g_PrintersPool);
  348. g_PrintersPool = NULL;
  349. }
  350. }
  351. BOOL
  352. WINAPI
  353. PrintersEtmInitialize (
  354. IN MIG_PLATFORMTYPEID Platform,
  355. IN PMIG_LOGCALLBACK LogCallback,
  356. IN PVOID Reserved
  357. )
  358. {
  359. TYPE_REGISTER printerTypeData;
  360. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  361. pLoadPrintersData ();
  362. ZeroMemory (&printerTypeData, sizeof (TYPE_REGISTER));
  363. printerTypeData.Priority = PRIORITY_PRINTER;
  364. if (Platform == PLATFORM_SOURCE) {
  365. printerTypeData.EnumFirstPhysicalObject = EnumFirstPrinter;
  366. printerTypeData.EnumNextPhysicalObject = EnumNextPrinter;
  367. printerTypeData.AbortEnumPhysicalObject = AbortEnumPrinter;
  368. printerTypeData.ConvertObjectToMultiSz = ConvertPrinterToMultiSz;
  369. printerTypeData.ConvertMultiSzToObject = ConvertMultiSzToPrinter;
  370. printerTypeData.GetNativeObjectName = GetNativePrinterName;
  371. printerTypeData.AcquirePhysicalObject = AcquirePrinter;
  372. printerTypeData.ReleasePhysicalObject = ReleasePrinter;
  373. printerTypeData.ConvertObjectContentToUnicode = ConvertPrinterContentToUnicode;
  374. printerTypeData.ConvertObjectContentToAnsi = ConvertPrinterContentToAnsi;
  375. printerTypeData.FreeConvertedObjectContent = FreeConvertedPrinterContent;
  376. g_PrinterTypeId = IsmRegisterObjectType (
  377. S_PRINTERS_NAME,
  378. TRUE,
  379. FALSE,
  380. &printerTypeData
  381. );
  382. } else {
  383. printerTypeData.EnumFirstPhysicalObject = EnumFirstPrinter;
  384. printerTypeData.EnumNextPhysicalObject = EnumNextPrinter;
  385. printerTypeData.AbortEnumPhysicalObject = AbortEnumPrinter;
  386. printerTypeData.ConvertObjectToMultiSz = ConvertPrinterToMultiSz;
  387. printerTypeData.ConvertMultiSzToObject = ConvertMultiSzToPrinter;
  388. printerTypeData.GetNativeObjectName = GetNativePrinterName;
  389. printerTypeData.AcquirePhysicalObject = AcquirePrinter;
  390. printerTypeData.ReleasePhysicalObject = ReleasePrinter;
  391. printerTypeData.DoesPhysicalObjectExist = DoesPrinterExist;
  392. printerTypeData.RemovePhysicalObject = RemovePrinter;
  393. printerTypeData.CreatePhysicalObject = CreatePrinter;
  394. printerTypeData.ReplacePhysicalObject = ReplacePrinter;
  395. printerTypeData.ConvertObjectContentToUnicode = ConvertPrinterContentToUnicode;
  396. printerTypeData.ConvertObjectContentToAnsi = ConvertPrinterContentToAnsi;
  397. printerTypeData.FreeConvertedObjectContent = FreeConvertedPrinterContent;
  398. g_PrinterTypeId = IsmRegisterObjectType (
  399. S_PRINTERS_NAME,
  400. TRUE,
  401. FALSE,
  402. &printerTypeData
  403. );
  404. }
  405. MYASSERT (g_PrinterTypeId);
  406. return TRUE;
  407. }
  408. VOID
  409. WINAPI
  410. PrintersEtmNewUserCreated (
  411. IN PCTSTR UserName,
  412. IN PCTSTR DomainName,
  413. IN PCTSTR UserProfileRoot,
  414. IN PSID UserSid
  415. )
  416. {
  417. // a new user was created, the printer operations need to be delayed
  418. PrintersTerminate ();
  419. g_DelayPrintersOp = TRUE;
  420. }
  421. BOOL
  422. WINAPI
  423. PrintersSgmInitialize (
  424. IN PMIG_LOGCALLBACK LogCallback,
  425. IN PVOID Reserved
  426. )
  427. {
  428. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  429. return TRUE;
  430. }
  431. BOOL
  432. WINAPI
  433. PrintersSgmParse (
  434. IN PVOID Reserved
  435. )
  436. {
  437. PCTSTR friendlyName;
  438. friendlyName = GetStringResource (MSG_PRINTERS_NAME);
  439. //IsmAddComponentAlias (
  440. // S_PRINTERS_NAME,
  441. // MASTERGROUP_SYSTEM,
  442. // friendlyName,
  443. // COMPONENT_NAME,
  444. // FALSE
  445. // );
  446. IsmAddComponentAlias (
  447. S_CORPNET_NAME,
  448. MASTERGROUP_SYSTEM,
  449. friendlyName,
  450. COMPONENT_NAME,
  451. FALSE
  452. );
  453. FreeStringResource (friendlyName);
  454. return TRUE;
  455. }
  456. UINT
  457. SgmPrintersCallback (
  458. IN PCMIG_OBJECTENUMDATA Data,
  459. IN ULONG_PTR CallerArg
  460. )
  461. {
  462. IsmAbandonObjectOnCollision (Data->ObjectTypeId, Data->ObjectName);
  463. IsmMakeApplyObject (Data->ObjectTypeId, Data->ObjectName);
  464. return CALLBACK_ENUM_CONTINUE;
  465. }
  466. BOOL
  467. WINAPI
  468. PrintersSgmQueueEnumeration (
  469. IN PVOID Reserved
  470. )
  471. {
  472. ENCODEDSTRHANDLE pattern;
  473. if (!IsmIsComponentSelected (S_PRINTERS_NAME, 0) &&
  474. !IsmIsComponentSelected (S_CORPNET_NAME, 0)
  475. ) {
  476. g_PrinterMigEnabled = FALSE;
  477. return TRUE;
  478. }
  479. g_PrinterMigEnabled = TRUE;
  480. pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, FALSE);
  481. IsmQueueEnumeration (
  482. g_PrinterTypeId,
  483. pattern,
  484. SgmPrintersCallback,
  485. (ULONG_PTR) 0,
  486. S_PRINTERS_NAME
  487. );
  488. IsmDestroyObjectHandle (pattern);
  489. return TRUE;
  490. }
  491. BOOL
  492. WINAPI
  493. PrintersVcmInitialize (
  494. IN PMIG_LOGCALLBACK LogCallback,
  495. IN PVOID Reserved
  496. )
  497. {
  498. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  499. return TRUE;
  500. }
  501. BOOL
  502. WINAPI
  503. PrintersVcmParse (
  504. IN PVOID Reserved
  505. )
  506. {
  507. return PrintersSgmParse (Reserved);
  508. }
  509. UINT
  510. VcmPrintersCallback (
  511. IN PCMIG_OBJECTENUMDATA Data,
  512. IN ULONG_PTR CallerArg
  513. )
  514. {
  515. IsmMakePersistentObject (Data->ObjectTypeId, Data->ObjectName);
  516. return CALLBACK_ENUM_CONTINUE;
  517. }
  518. BOOL
  519. WINAPI
  520. PrintersVcmQueueEnumeration (
  521. IN PVOID Reserved
  522. )
  523. {
  524. ENCODEDSTRHANDLE pattern;
  525. if (!IsmIsComponentSelected (S_PRINTERS_NAME, 0) &&
  526. !IsmIsComponentSelected (S_CORPNET_NAME, 0)
  527. ) {
  528. g_PrinterMigEnabled = FALSE;
  529. return TRUE;
  530. }
  531. g_PrinterMigEnabled = TRUE;
  532. pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, FALSE);
  533. IsmQueueEnumeration (
  534. g_PrinterTypeId,
  535. pattern,
  536. VcmPrintersCallback,
  537. (ULONG_PTR) 0,
  538. S_PRINTERS_NAME
  539. );
  540. IsmDestroyObjectHandle (pattern);
  541. return TRUE;
  542. }
  543. BOOL
  544. pEnumPrinterWorker (
  545. OUT PMIG_TYPEOBJECTENUM EnumPtr,
  546. IN PPRINTER_ENUM PrinterEnum
  547. )
  548. {
  549. if (EnumPtr->ObjectNode) {
  550. IsmDestroyObjectString (EnumPtr->ObjectNode);
  551. EnumPtr->ObjectNode = NULL;
  552. }
  553. if (EnumPtr->ObjectLeaf) {
  554. IsmDestroyObjectString (EnumPtr->ObjectLeaf);
  555. EnumPtr->ObjectLeaf = NULL;
  556. }
  557. do {
  558. EnumPtr->ObjectName = IsmCreateObjectHandle (PrinterEnum->HashData.String, NULL);
  559. if (!ObsPatternMatch (PrinterEnum->Pattern, EnumPtr->ObjectName)) {
  560. if (!EnumNextHashTableString (&PrinterEnum->HashData)) {
  561. AbortEnumPrinter (EnumPtr);
  562. return FALSE;
  563. }
  564. continue;
  565. }
  566. EnumPtr->NativeObjectName = PrinterEnum->HashData.String;
  567. IsmCreateObjectStringsFromHandle (EnumPtr->ObjectName, &EnumPtr->ObjectNode, &EnumPtr->ObjectLeaf);
  568. EnumPtr->Level = 1;
  569. EnumPtr->SubLevel = 0;
  570. EnumPtr->IsLeaf = FALSE;
  571. EnumPtr->IsNode = TRUE;
  572. EnumPtr->Details.DetailsSize = 0;
  573. EnumPtr->Details.DetailsData = NULL;
  574. return TRUE;
  575. } while (TRUE);
  576. }
  577. BOOL
  578. EnumFirstPrinter (
  579. IN OUT PMIG_TYPEOBJECTENUM EnumPtr, CALLER_INITIALIZED
  580. IN MIG_OBJECTSTRINGHANDLE Pattern,
  581. IN UINT MaxLevel
  582. )
  583. {
  584. PPRINTER_ENUM printerEnum = NULL;
  585. if (!g_PrintersTable) {
  586. return FALSE;
  587. }
  588. printerEnum = (PPRINTER_ENUM) PmGetMemory (g_PrintersPool, sizeof (PRINTER_ENUM));
  589. printerEnum->Pattern = PmDuplicateString (g_PrintersPool, Pattern);
  590. EnumPtr->EtmHandle = (LONG_PTR) printerEnum;
  591. if (EnumFirstHashTableString (&printerEnum->HashData, g_PrintersTable)) {
  592. return pEnumPrinterWorker (EnumPtr, printerEnum);
  593. } else {
  594. AbortEnumPrinter (EnumPtr);
  595. return FALSE;
  596. }
  597. }
  598. BOOL
  599. EnumNextPrinter (
  600. IN OUT PMIG_TYPEOBJECTENUM EnumPtr
  601. )
  602. {
  603. PPRINTER_ENUM printerEnum = NULL;
  604. if (EnumPtr->ObjectName) {
  605. IsmDestroyObjectHandle (EnumPtr->ObjectName);
  606. EnumPtr->ObjectName = NULL;
  607. }
  608. printerEnum = (PPRINTER_ENUM)(EnumPtr->EtmHandle);
  609. if (!printerEnum) {
  610. return FALSE;
  611. }
  612. if (EnumNextHashTableString (&printerEnum->HashData)) {
  613. return pEnumPrinterWorker (EnumPtr, printerEnum);
  614. } else {
  615. AbortEnumPrinter (EnumPtr);
  616. return FALSE;
  617. }
  618. }
  619. VOID
  620. AbortEnumPrinter (
  621. IN OUT PMIG_TYPEOBJECTENUM EnumPtr
  622. )
  623. {
  624. PPRINTER_ENUM printerEnum = NULL;
  625. if (EnumPtr->ObjectName) {
  626. IsmDestroyObjectHandle (EnumPtr->ObjectName);
  627. EnumPtr->ObjectName = NULL;
  628. }
  629. if (EnumPtr->ObjectNode) {
  630. IsmDestroyObjectString (EnumPtr->ObjectNode);
  631. EnumPtr->ObjectNode = NULL;
  632. }
  633. if (EnumPtr->ObjectLeaf) {
  634. IsmDestroyObjectString (EnumPtr->ObjectLeaf);
  635. EnumPtr->ObjectLeaf = NULL;
  636. }
  637. printerEnum = (PPRINTER_ENUM)(EnumPtr->EtmHandle);
  638. if (!printerEnum) {
  639. return;
  640. }
  641. PmReleaseMemory (g_PrintersPool, printerEnum->Pattern);
  642. PmReleaseMemory (g_PrintersPool, printerEnum);
  643. ZeroMemory (EnumPtr, sizeof (MIG_TYPEOBJECTENUM));
  644. }
  645. BOOL
  646. AcquirePrinter (
  647. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  648. OUT PMIG_CONTENT ObjectContent, CALLER_INITIALIZED
  649. IN MIG_CONTENTTYPE ContentType,
  650. IN UINT MemoryContentLimit
  651. )
  652. {
  653. PCTSTR node;
  654. PCTSTR leaf;
  655. PPRINTER_DATA printerData = NULL;
  656. BOOL result = FALSE;
  657. if (!ObjectContent) {
  658. return FALSE;
  659. }
  660. if (ContentType == CONTENTTYPE_FILE) {
  661. // nobody should request this as a file
  662. MYASSERT (FALSE);
  663. return FALSE;
  664. }
  665. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  666. if (HtFindStringEx (g_PrintersTable, node, (PVOID)(&printerData), FALSE)) {
  667. ObjectContent->MemoryContent.ContentBytes = (PCBYTE)printerData;
  668. ObjectContent->MemoryContent.ContentSize = sizeof (PRINTER_DATA);
  669. result = TRUE;
  670. }
  671. IsmDestroyObjectString (node);
  672. IsmDestroyObjectString (leaf);
  673. }
  674. return result;
  675. }
  676. BOOL
  677. ReleasePrinter (
  678. IN OUT PMIG_CONTENT ObjectContent
  679. )
  680. {
  681. if (ObjectContent) {
  682. ZeroMemory (ObjectContent, sizeof (MIG_CONTENT));
  683. }
  684. return TRUE;
  685. }
  686. BOOL
  687. DoesPrinterExist (
  688. IN MIG_OBJECTSTRINGHANDLE ObjectName
  689. )
  690. {
  691. PCTSTR node;
  692. PCTSTR leaf;
  693. PPRINTER_DATA printerData = NULL;
  694. BOOL result = FALSE;
  695. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  696. if (g_PrintersTable &&
  697. HtFindStringEx (g_PrintersTable, node, (PVOID)(&printerData), FALSE)
  698. ) {
  699. result = TRUE;
  700. }
  701. IsmDestroyObjectString (node);
  702. IsmDestroyObjectString (leaf);
  703. }
  704. return result;
  705. }
  706. BOOL
  707. RemovePrinter (
  708. IN MIG_OBJECTSTRINGHANDLE ObjectName
  709. )
  710. {
  711. PCTSTR node;
  712. PCTSTR leaf;
  713. BOOL result = FALSE;
  714. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  715. if (node && (!leaf)) {
  716. result = DeletePrinterConnection ((PTSTR)node);
  717. }
  718. IsmDestroyObjectString (node);
  719. IsmDestroyObjectString (leaf);
  720. }
  721. return result;
  722. }
  723. BOOL
  724. CreatePrinter (
  725. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  726. IN PMIG_CONTENT ObjectContent
  727. )
  728. {
  729. PCTSTR node;
  730. PCTSTR leaf;
  731. PPRINTER_DATA printerData;
  732. HANDLE printerHandle = NULL;
  733. BOOL result = FALSE;
  734. UINT devModeSize;
  735. PPRINTER_INFO_2 printerInfo;
  736. UINT printerInfoSize;
  737. PDEVMODE devMode;
  738. if (!ObjectContent->ContentInFile) {
  739. if (ObjectContent->MemoryContent.ContentBytes && ObjectContent->MemoryContent.ContentSize) {
  740. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  741. if (node && (!leaf)) {
  742. if (g_DelayPrintersOp) {
  743. // we need to delay this operation
  744. // record delayed printer replace operation
  745. IsmRecordDelayedOperation (
  746. JRNOP_CREATE,
  747. g_PrinterTypeId,
  748. ObjectName,
  749. ObjectContent
  750. );
  751. result = TRUE;
  752. } else {
  753. // record printer creation
  754. IsmRecordOperation (
  755. JRNOP_CREATE,
  756. g_PrinterTypeId,
  757. ObjectName
  758. );
  759. result = AddPrinterConnection ((PTSTR)node);
  760. if (result) {
  761. printerData = (PPRINTER_DATA)(ObjectContent->MemoryContent.ContentBytes);
  762. if (printerData->dmFields) {
  763. // let's restore printer settings
  764. if (OpenPrinter ((PTSTR)node, &printerHandle, NULL)) {
  765. if (GetPrinter (printerHandle, 2, 0, 0, &printerInfoSize) || (GetLastError () == ERROR_INSUFFICIENT_BUFFER)) {
  766. printerInfo = PmGetMemory (g_PrintersPool, (printerInfoSize > sizeof (PRINTER_INFO_2))?printerInfoSize:sizeof (PRINTER_INFO_2));
  767. ZeroMemory (printerInfo, (printerInfoSize > sizeof (PRINTER_INFO_2))?printerInfoSize:sizeof (PRINTER_INFO_2));
  768. if (GetPrinter (printerHandle, 2, (PBYTE)printerInfo, printerInfoSize, &printerInfoSize)) {
  769. if (printerInfo->pDevMode) {
  770. devMode = printerInfo->pDevMode;
  771. } else {
  772. devModeSize = DocumentProperties (NULL, printerHandle, (PTSTR)node, NULL, NULL, 0);
  773. if (devModeSize) {
  774. devMode = PmGetMemory (g_PrintersPool, (devModeSize > sizeof (DEVMODE))?devModeSize:sizeof (DEVMODE));
  775. if (!DocumentProperties (NULL, printerHandle, (PTSTR)node, devMode, NULL, DM_OUT_BUFFER) == IDOK) {
  776. PmReleaseMemory (g_PrintersPool, devMode);
  777. devMode = NULL;
  778. } else {
  779. printerInfo->pDevMode = devMode;
  780. }
  781. }
  782. }
  783. if (devMode) {
  784. if ((devMode->dmFields & DM_ORIENTATION) && (printerData->dmFields & DM_ORIENTATION)) {
  785. devMode->dmOrientation = printerData->dmOrientation;
  786. }
  787. if ((devMode->dmFields & DM_PAPERSIZE) && (printerData->dmFields & DM_PAPERSIZE)) {
  788. devMode->dmPaperSize = printerData->dmPaperSize;
  789. }
  790. if ((devMode->dmFields & DM_PAPERLENGTH) && (printerData->dmFields & DM_PAPERLENGTH)) {
  791. devMode->dmPaperLength = printerData->dmPaperLength;
  792. }
  793. if ((devMode->dmFields & DM_PAPERWIDTH) && (printerData->dmFields & DM_PAPERWIDTH)) {
  794. devMode->dmPaperWidth = printerData->dmPaperWidth;
  795. }
  796. if ((devMode->dmFields & DM_SCALE) && (printerData->dmFields & DM_SCALE)) {
  797. devMode->dmScale = printerData->dmScale;
  798. }
  799. if ((devMode->dmFields & DM_POSITION) && (printerData->dmFields & DM_POSITION)) {
  800. CopyMemory (&devMode->dmScale, &printerData->dmScale, sizeof(POINTL));
  801. }
  802. if ((devMode->dmFields & DM_NUP) && (printerData->dmFields & DM_NUP)) {
  803. devMode->dmNup = printerData->dmNup;
  804. }
  805. if ((devMode->dmFields & DM_COPIES) && (printerData->dmFields & DM_COPIES)) {
  806. devMode->dmCopies = printerData->dmCopies;
  807. }
  808. if ((devMode->dmFields & DM_DEFAULTSOURCE) && (printerData->dmFields & DM_DEFAULTSOURCE)) {
  809. devMode->dmDefaultSource = printerData->dmDefaultSource;
  810. }
  811. if ((devMode->dmFields & DM_PRINTQUALITY) && (printerData->dmFields & DM_PRINTQUALITY)) {
  812. devMode->dmPrintQuality = printerData->dmPrintQuality;
  813. }
  814. if ((devMode->dmFields & DM_COLOR) && (printerData->dmFields & DM_COLOR)) {
  815. devMode->dmColor = printerData->dmColor;
  816. }
  817. if ((devMode->dmFields & DM_DUPLEX) && (printerData->dmFields & DM_DUPLEX)) {
  818. devMode->dmDuplex = printerData->dmDuplex;
  819. }
  820. if ((devMode->dmFields & DM_YRESOLUTION) && (printerData->dmFields & DM_YRESOLUTION)) {
  821. devMode->dmYResolution = printerData->dmYResolution;
  822. }
  823. if ((devMode->dmFields & DM_TTOPTION) && (printerData->dmFields & DM_TTOPTION)) {
  824. devMode->dmTTOption = printerData->dmTTOption;
  825. }
  826. if ((devMode->dmFields & DM_COLLATE) && (printerData->dmFields & DM_COLLATE)) {
  827. devMode->dmCollate = printerData->dmCollate;
  828. }
  829. if ((devMode->dmFields & DM_FORMNAME) && (printerData->dmFields & DM_FORMNAME)) {
  830. CopyMemory (devMode->dmFormName, printerData->dmFormName, sizeof (devMode->dmFormName));
  831. }
  832. if ((devMode->dmFields & DM_LOGPIXELS) && (printerData->dmFields & DM_LOGPIXELS)) {
  833. devMode->dmLogPixels = printerData->dmLogPixels;
  834. }
  835. if ((devMode->dmFields & DM_BITSPERPEL) && (printerData->dmFields & DM_BITSPERPEL)) {
  836. devMode->dmBitsPerPel = printerData->dmBitsPerPel;
  837. }
  838. if ((devMode->dmFields & DM_PELSWIDTH) && (printerData->dmFields & DM_PELSWIDTH)) {
  839. devMode->dmPelsWidth = printerData->dmPelsWidth;
  840. }
  841. if ((devMode->dmFields & DM_PELSHEIGHT) && (printerData->dmFields & DM_PELSHEIGHT)) {
  842. devMode->dmPelsHeight = printerData->dmPelsHeight;
  843. }
  844. if ((devMode->dmFields & DM_DISPLAYFLAGS) && (printerData->dmFields & DM_DISPLAYFLAGS)) {
  845. devMode->dmDisplayFlags = printerData->dmDisplayFlags;
  846. }
  847. if ((devMode->dmFields & DM_DISPLAYFREQUENCY) && (printerData->dmFields & DM_DISPLAYFREQUENCY)) {
  848. devMode->dmDisplayFrequency = printerData->dmDisplayFrequency;
  849. }
  850. if ((devMode->dmFields & DM_ICMMETHOD) && (printerData->dmFields & DM_ICMMETHOD)) {
  851. devMode->dmICMMethod = printerData->dmICMMethod;
  852. }
  853. if ((devMode->dmFields & DM_ICMINTENT) && (printerData->dmFields & DM_ICMINTENT)) {
  854. devMode->dmICMIntent = printerData->dmICMIntent;
  855. }
  856. if ((devMode->dmFields & DM_MEDIATYPE) && (printerData->dmFields & DM_MEDIATYPE)) {
  857. devMode->dmMediaType = printerData->dmMediaType;
  858. }
  859. if ((devMode->dmFields & DM_DITHERTYPE) && (printerData->dmFields & DM_DITHERTYPE)) {
  860. devMode->dmDitherType = printerData->dmDitherType;
  861. }
  862. if ((devMode->dmFields & DM_PANNINGWIDTH) && (printerData->dmFields & DM_PANNINGWIDTH)) {
  863. devMode->dmPanningWidth = printerData->dmPanningWidth;
  864. }
  865. if ((devMode->dmFields & DM_PANNINGHEIGHT) && (printerData->dmFields & DM_PANNINGHEIGHT)) {
  866. devMode->dmPanningHeight = printerData->dmPanningHeight;
  867. }
  868. if (DocumentProperties (NULL, printerHandle, (PTSTR)node, devMode, devMode, DM_IN_BUFFER | DM_OUT_BUFFER) == IDOK) {
  869. SetPrinter (printerHandle, 2, (PBYTE)printerInfo, 0);
  870. } else {
  871. DEBUGMSG ((DBG_PRINTERS, "Failed to restore printer %s settings", node));
  872. }
  873. if (devMode != printerInfo->pDevMode) {
  874. PmReleaseMemory (g_PrintersPool, devMode);
  875. }
  876. } else {
  877. DEBUGMSG ((DBG_PRINTERS, "Failed to restore printer %s settings", node));
  878. }
  879. } else {
  880. DEBUGMSG ((DBG_PRINTERS, "Failed to restore printer %s settings", node));
  881. }
  882. PmReleaseMemory (g_PrintersPool, printerInfo);
  883. } else {
  884. DEBUGMSG ((DBG_PRINTERS, "Failed to restore printer %s settings", node));
  885. }
  886. ClosePrinter (printerHandle);
  887. } else {
  888. DEBUGMSG ((DBG_PRINTERS, "Failed to restore printer %s settings", node));
  889. }
  890. }
  891. if (printerData && printerData->Default) {
  892. result = SetDefaultPrinter (node);
  893. if (!result) {
  894. DEBUGMSG ((DBG_PRINTERS, "Failed to set %s as default printer", node));
  895. }
  896. }
  897. } else {
  898. DEBUGMSG ((DBG_PRINTERS, "Failed to add printer connection for %s", node));
  899. }
  900. }
  901. }
  902. IsmDestroyObjectString (node);
  903. IsmDestroyObjectString (leaf);
  904. }
  905. }
  906. }
  907. return result;
  908. }
  909. BOOL
  910. ReplacePrinter (
  911. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  912. IN PMIG_CONTENT ObjectContent
  913. )
  914. {
  915. BOOL result = TRUE;
  916. if (g_DelayPrintersOp) {
  917. // we need to delay this operation
  918. // record delayed printer replace operation
  919. IsmRecordDelayedOperation (
  920. JRNOP_REPLACE,
  921. g_PrinterTypeId,
  922. ObjectName,
  923. ObjectContent
  924. );
  925. result = TRUE;
  926. } else {
  927. // we are going to delete any existing printers with this name,
  928. // and create a new one
  929. if (DoesPrinterExist (ObjectName)) {
  930. result = RemovePrinter (ObjectName);
  931. }
  932. if (result) {
  933. result = CreatePrinter (ObjectName, ObjectContent);
  934. }
  935. }
  936. return result;
  937. }
  938. PCTSTR
  939. ConvertPrinterToMultiSz (
  940. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  941. IN PMIG_CONTENT ObjectContent
  942. )
  943. {
  944. PCTSTR node, leaf;
  945. PTSTR result = NULL;
  946. BOOL bresult = TRUE;
  947. PPRINTER_DATA printerData;
  948. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  949. MYASSERT (!leaf);
  950. g_PrinterConversionBuff.End = 0;
  951. GbCopyQuotedString (&g_PrinterConversionBuff, node);
  952. MYASSERT (ObjectContent->Details.DetailsSize == 0);
  953. MYASSERT (!ObjectContent->ContentInFile);
  954. MYASSERT (ObjectContent->MemoryContent.ContentSize = sizeof (PRINTER_DATA));
  955. if ((!ObjectContent->ContentInFile) &&
  956. (ObjectContent->MemoryContent.ContentSize) &&
  957. (ObjectContent->MemoryContent.ContentSize == sizeof (PRINTER_DATA)) &&
  958. (ObjectContent->MemoryContent.ContentBytes)
  959. ) {
  960. printerData = (PPRINTER_DATA)ObjectContent->MemoryContent.ContentBytes;
  961. wsprintf (
  962. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  963. TEXT("0x%08X"),
  964. printerData->Default
  965. );
  966. wsprintf (
  967. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  968. TEXT("0x%08X"),
  969. printerData->dmFields
  970. );
  971. wsprintf (
  972. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  973. TEXT("0x%08X"),
  974. printerData->dmOrientation
  975. );
  976. wsprintf (
  977. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  978. TEXT("0x%08X"),
  979. printerData->dmPaperSize
  980. );
  981. wsprintf (
  982. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  983. TEXT("0x%08X"),
  984. printerData->dmPaperLength
  985. );
  986. wsprintf (
  987. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  988. TEXT("0x%08X"),
  989. printerData->dmPaperWidth
  990. );
  991. wsprintf (
  992. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  993. TEXT("0x%08X"),
  994. printerData->dmPosition.x
  995. );
  996. wsprintf (
  997. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  998. TEXT("0x%08X"),
  999. printerData->dmPosition.y
  1000. );
  1001. wsprintf (
  1002. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1003. TEXT("0x%08X"),
  1004. printerData->dmScale
  1005. );
  1006. wsprintf (
  1007. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1008. TEXT("0x%08X"),
  1009. printerData->dmCopies
  1010. );
  1011. wsprintf (
  1012. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1013. TEXT("0x%08X"),
  1014. printerData->dmDefaultSource
  1015. );
  1016. wsprintf (
  1017. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1018. TEXT("0x%08X"),
  1019. printerData->dmPrintQuality
  1020. );
  1021. wsprintf (
  1022. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1023. TEXT("0x%08X"),
  1024. printerData->dmColor
  1025. );
  1026. wsprintf (
  1027. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1028. TEXT("0x%08X"),
  1029. printerData->dmDuplex
  1030. );
  1031. wsprintf (
  1032. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1033. TEXT("0x%08X"),
  1034. printerData->dmYResolution
  1035. );
  1036. wsprintf (
  1037. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1038. TEXT("0x%08X"),
  1039. printerData->dmTTOption
  1040. );
  1041. wsprintf (
  1042. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1043. TEXT("0x%08X"),
  1044. printerData->dmCollate
  1045. );
  1046. GbCopyQuotedString (&g_PrinterConversionBuff, printerData->dmFormName);
  1047. wsprintf (
  1048. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1049. TEXT("0x%08X"),
  1050. printerData->dmLogPixels
  1051. );
  1052. wsprintf (
  1053. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1054. TEXT("0x%08X"),
  1055. printerData->dmBitsPerPel
  1056. );
  1057. wsprintf (
  1058. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1059. TEXT("0x%08X"),
  1060. printerData->dmPelsWidth
  1061. );
  1062. wsprintf (
  1063. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1064. TEXT("0x%08X"),
  1065. printerData->dmPelsHeight
  1066. );
  1067. wsprintf (
  1068. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1069. TEXT("0x%08X"),
  1070. printerData->dmDisplayFlags
  1071. );
  1072. wsprintf (
  1073. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1074. TEXT("0x%08X"),
  1075. printerData->dmNup
  1076. );
  1077. wsprintf (
  1078. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1079. TEXT("0x%08X"),
  1080. printerData->dmDisplayFrequency
  1081. );
  1082. wsprintf (
  1083. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1084. TEXT("0x%08X"),
  1085. printerData->dmICMMethod
  1086. );
  1087. wsprintf (
  1088. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1089. TEXT("0x%08X"),
  1090. printerData->dmICMIntent
  1091. );
  1092. wsprintf (
  1093. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1094. TEXT("0x%08X"),
  1095. printerData->dmMediaType
  1096. );
  1097. wsprintf (
  1098. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1099. TEXT("0x%08X"),
  1100. printerData->dmDitherType
  1101. );
  1102. wsprintf (
  1103. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1104. TEXT("0x%08X"),
  1105. printerData->dmPanningWidth
  1106. );
  1107. wsprintf (
  1108. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1109. TEXT("0x%08X"),
  1110. printerData->dmPanningHeight
  1111. );
  1112. } else {
  1113. bresult = FALSE;
  1114. }
  1115. if (bresult) {
  1116. GbCopyString (&g_PrinterConversionBuff, TEXT(""));
  1117. result = IsmGetMemory (g_PrinterConversionBuff.End);
  1118. CopyMemory (result, g_PrinterConversionBuff.Buf, g_PrinterConversionBuff.End);
  1119. }
  1120. g_PrinterConversionBuff.End = 0;
  1121. IsmDestroyObjectString (node);
  1122. IsmDestroyObjectString (leaf);
  1123. }
  1124. return result;
  1125. }
  1126. BOOL
  1127. ConvertMultiSzToPrinter (
  1128. IN PCTSTR ObjectMultiSz,
  1129. OUT MIG_OBJECTSTRINGHANDLE *ObjectName,
  1130. OUT PMIG_CONTENT ObjectContent OPTIONAL
  1131. )
  1132. {
  1133. MULTISZ_ENUM multiSzEnum;
  1134. PCTSTR name = NULL;
  1135. PRINTER_DATA printerData;
  1136. DWORD dummy;
  1137. UINT index;
  1138. g_PrinterConversionBuff.End = 0;
  1139. ZeroMemory (&printerData, sizeof (PRINTER_DATA));
  1140. if (EnumFirstMultiSz (&multiSzEnum, ObjectMultiSz)) {
  1141. index = 0;
  1142. do {
  1143. if (index == 0) {
  1144. name = multiSzEnum.CurrentString;
  1145. }
  1146. if (index == 1) {
  1147. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1148. printerData.Default = dummy;
  1149. }
  1150. if (index == 2) {
  1151. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1152. printerData.dmFields = dummy;
  1153. }
  1154. if (index == 3) {
  1155. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1156. printerData.dmOrientation = (SHORT)dummy;
  1157. }
  1158. if (index == 4) {
  1159. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1160. printerData.dmPaperSize = (SHORT)dummy;
  1161. }
  1162. if (index == 5) {
  1163. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1164. printerData.dmPaperLength = (SHORT)dummy;
  1165. }
  1166. if (index == 6) {
  1167. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1168. printerData.dmPaperWidth = (SHORT)dummy;
  1169. }
  1170. if (index == 7) {
  1171. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1172. printerData.dmPosition.x = dummy;
  1173. }
  1174. if (index == 8) {
  1175. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1176. printerData.dmPosition.y = dummy;
  1177. }
  1178. if (index == 9) {
  1179. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1180. printerData.dmScale = (SHORT)dummy;
  1181. }
  1182. if (index == 10) {
  1183. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1184. printerData.dmCopies = (SHORT)dummy;
  1185. }
  1186. if (index == 11) {
  1187. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1188. printerData.dmDefaultSource = (SHORT)dummy;
  1189. }
  1190. if (index == 12) {
  1191. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1192. printerData.dmPrintQuality = (SHORT)dummy;
  1193. }
  1194. if (index == 13) {
  1195. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1196. printerData.dmColor = (SHORT)dummy;
  1197. }
  1198. if (index == 14) {
  1199. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1200. printerData.dmDuplex = (SHORT)dummy;
  1201. }
  1202. if (index == 15) {
  1203. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1204. printerData.dmYResolution = (SHORT)dummy;
  1205. }
  1206. if (index == 16) {
  1207. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1208. printerData.dmTTOption = (SHORT)dummy;
  1209. }
  1210. if (index == 17) {
  1211. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1212. printerData.dmCollate = (SHORT)dummy;
  1213. }
  1214. if (index == 18) {
  1215. if (!StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
  1216. StringCopyTcharCount (printerData.dmFormName, multiSzEnum.CurrentString, CCHFORMNAME);
  1217. }
  1218. }
  1219. if (index == 19) {
  1220. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1221. printerData.dmLogPixels = (WORD)dummy;
  1222. }
  1223. if (index == 20) {
  1224. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1225. printerData.dmBitsPerPel = dummy;
  1226. }
  1227. if (index == 21) {
  1228. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1229. printerData.dmPelsWidth = dummy;
  1230. }
  1231. if (index == 22) {
  1232. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1233. printerData.dmPelsHeight = dummy;
  1234. }
  1235. if (index == 23) {
  1236. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1237. printerData.dmDisplayFlags = dummy;
  1238. }
  1239. if (index == 24) {
  1240. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1241. printerData.dmNup = dummy;
  1242. }
  1243. if (index == 25) {
  1244. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1245. printerData.dmDisplayFrequency = dummy;
  1246. }
  1247. if (index == 26) {
  1248. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1249. printerData.dmICMMethod = dummy;
  1250. }
  1251. if (index == 27) {
  1252. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1253. printerData.dmICMIntent = dummy;
  1254. }
  1255. if (index == 28) {
  1256. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1257. printerData.dmMediaType = dummy;
  1258. }
  1259. if (index == 29) {
  1260. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1261. printerData.dmDitherType = dummy;
  1262. }
  1263. if (index == 30) {
  1264. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1265. printerData.dmPanningWidth = dummy;
  1266. }
  1267. if (index == 31) {
  1268. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1269. printerData.dmPanningHeight = dummy;
  1270. }
  1271. index ++;
  1272. } while (EnumNextMultiSz (&multiSzEnum));
  1273. }
  1274. if (!name) {
  1275. return FALSE;
  1276. }
  1277. if (ObjectContent) {
  1278. ObjectContent->ContentInFile = FALSE;
  1279. ObjectContent->MemoryContent.ContentSize = sizeof (PRINTER_DATA);
  1280. ObjectContent->MemoryContent.ContentBytes = IsmGetMemory (ObjectContent->MemoryContent.ContentSize);
  1281. CopyMemory (
  1282. (PBYTE)ObjectContent->MemoryContent.ContentBytes,
  1283. &printerData,
  1284. ObjectContent->MemoryContent.ContentSize
  1285. );
  1286. ObjectContent->Details.DetailsSize = 0;
  1287. ObjectContent->Details.DetailsData = NULL;
  1288. }
  1289. *ObjectName = IsmCreateObjectHandle (name, NULL);
  1290. return TRUE;
  1291. }
  1292. PCTSTR
  1293. GetNativePrinterName (
  1294. IN MIG_OBJECTSTRINGHANDLE ObjectName
  1295. )
  1296. {
  1297. PCTSTR node, leaf;
  1298. PTSTR nodePtr = NULL, nodeBegin = NULL;
  1299. UINT strSize = 0;
  1300. PTSTR result = NULL;
  1301. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  1302. if (node) {
  1303. nodePtr = _tcsrchr (node, TEXT('\\'));
  1304. if (nodePtr) {
  1305. *nodePtr = 0;
  1306. nodePtr ++;
  1307. }
  1308. nodeBegin = (PTSTR)node;
  1309. while (*nodeBegin == TEXT('\\')) {
  1310. nodeBegin ++;
  1311. }
  1312. if (nodePtr) {
  1313. strSize = CharCount (nodePtr) + \
  1314. CharCount (TEXT(" on ")) + \
  1315. CharCount (nodeBegin) + \
  1316. 1;
  1317. result = IsmGetMemory (strSize * sizeof (TCHAR));
  1318. _tcscpy (result, nodePtr);
  1319. _tcscat (result, TEXT(" on "));
  1320. _tcscat (result, nodeBegin);
  1321. } else {
  1322. strSize = CharCount (nodeBegin) + \
  1323. 1;
  1324. result = IsmGetMemory (strSize * sizeof (TCHAR));
  1325. _tcscpy (result, nodeBegin);
  1326. }
  1327. }
  1328. IsmDestroyObjectString (node);
  1329. IsmDestroyObjectString (leaf);
  1330. }
  1331. return result;
  1332. }
  1333. PMIG_CONTENT
  1334. ConvertPrinterContentToUnicode (
  1335. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1336. IN PMIG_CONTENT ObjectContent
  1337. )
  1338. {
  1339. PMIG_CONTENT result = NULL;
  1340. if (!ObjectContent) {
  1341. return result;
  1342. }
  1343. if (ObjectContent->ContentInFile) {
  1344. return result;
  1345. }
  1346. result = IsmGetMemory (sizeof (MIG_CONTENT));
  1347. if (result) {
  1348. CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
  1349. if ((ObjectContent->MemoryContent.ContentSize != 0) &&
  1350. (ObjectContent->MemoryContent.ContentBytes != NULL)
  1351. ) {
  1352. // convert Printer content
  1353. result->MemoryContent.ContentBytes = IsmGetMemory (sizeof (PRINTER_DATAW));
  1354. if (result->MemoryContent.ContentBytes) {
  1355. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->Default =
  1356. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->Default;
  1357. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmFields =
  1358. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmFields;
  1359. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmOrientation =
  1360. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmOrientation;
  1361. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPaperSize =
  1362. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPaperSize;
  1363. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPaperLength =
  1364. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPaperLength;
  1365. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPaperWidth =
  1366. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPaperWidth;
  1367. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPosition.x =
  1368. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPosition.x;
  1369. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPosition.y =
  1370. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPosition.y;
  1371. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmScale =
  1372. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmScale;
  1373. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmCopies =
  1374. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmCopies;
  1375. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmDefaultSource =
  1376. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmDefaultSource;
  1377. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPrintQuality =
  1378. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPrintQuality;
  1379. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmColor =
  1380. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmColor;
  1381. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmDuplex =
  1382. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmDuplex;
  1383. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmYResolution =
  1384. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmYResolution;
  1385. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmTTOption =
  1386. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmTTOption;
  1387. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmCollate =
  1388. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmCollate;
  1389. DirectDbcsToUnicodeN (
  1390. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmFormName,
  1391. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmFormName,
  1392. CCHFORMNAME
  1393. );
  1394. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmLogPixels =
  1395. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmLogPixels;
  1396. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmBitsPerPel =
  1397. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmBitsPerPel;
  1398. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPelsWidth =
  1399. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPelsWidth;
  1400. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPelsHeight =
  1401. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPelsHeight;
  1402. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmDisplayFlags =
  1403. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmDisplayFlags;
  1404. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmNup =
  1405. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmNup;
  1406. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmDisplayFrequency =
  1407. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmDisplayFrequency;
  1408. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmICMMethod =
  1409. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmICMMethod;
  1410. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmICMIntent =
  1411. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmICMIntent;
  1412. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmMediaType =
  1413. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmMediaType;
  1414. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmDitherType =
  1415. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmDitherType;
  1416. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPanningWidth =
  1417. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPanningWidth;
  1418. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPanningHeight =
  1419. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPanningHeight;
  1420. result->MemoryContent.ContentSize = sizeof (PRINTER_DATAW);
  1421. }
  1422. }
  1423. }
  1424. return result;
  1425. }
  1426. PMIG_CONTENT
  1427. ConvertPrinterContentToAnsi (
  1428. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1429. IN PMIG_CONTENT ObjectContent
  1430. )
  1431. {
  1432. PMIG_CONTENT result = NULL;
  1433. if (!ObjectContent) {
  1434. return result;
  1435. }
  1436. if (ObjectContent->ContentInFile) {
  1437. return result;
  1438. }
  1439. result = IsmGetMemory (sizeof (MIG_CONTENT));
  1440. if (result) {
  1441. CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
  1442. if ((ObjectContent->MemoryContent.ContentSize != 0) &&
  1443. (ObjectContent->MemoryContent.ContentBytes != NULL)
  1444. ) {
  1445. // convert Printer content
  1446. result->MemoryContent.ContentBytes = IsmGetMemory (sizeof (PRINTER_DATAW));
  1447. if (result->MemoryContent.ContentBytes) {
  1448. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->Default =
  1449. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->Default;
  1450. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmFields =
  1451. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmFields;
  1452. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmOrientation =
  1453. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmOrientation;
  1454. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPaperSize =
  1455. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPaperSize;
  1456. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPaperLength =
  1457. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPaperLength;
  1458. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPaperWidth =
  1459. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPaperWidth;
  1460. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPosition.x =
  1461. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPosition.x;
  1462. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPosition.y =
  1463. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPosition.y;
  1464. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmScale =
  1465. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmScale;
  1466. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmCopies =
  1467. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmCopies;
  1468. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmDefaultSource =
  1469. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmDefaultSource;
  1470. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPrintQuality =
  1471. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPrintQuality;
  1472. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmColor =
  1473. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmColor;
  1474. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmDuplex =
  1475. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmDuplex;
  1476. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmYResolution =
  1477. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmYResolution;
  1478. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmTTOption =
  1479. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmTTOption;
  1480. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmCollate =
  1481. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmCollate;
  1482. DirectUnicodeToDbcsN (
  1483. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmFormName,
  1484. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmFormName,
  1485. CCHFORMNAME
  1486. );
  1487. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmLogPixels =
  1488. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmLogPixels;
  1489. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmBitsPerPel =
  1490. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmBitsPerPel;
  1491. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPelsWidth =
  1492. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPelsWidth;
  1493. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPelsHeight =
  1494. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPelsHeight;
  1495. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmDisplayFlags =
  1496. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmDisplayFlags;
  1497. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmNup =
  1498. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmNup;
  1499. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmDisplayFrequency =
  1500. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmDisplayFrequency;
  1501. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmICMMethod =
  1502. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmICMMethod;
  1503. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmICMIntent =
  1504. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmICMIntent;
  1505. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmMediaType =
  1506. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmMediaType;
  1507. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmDitherType =
  1508. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmDitherType;
  1509. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPanningWidth =
  1510. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPanningWidth;
  1511. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPanningHeight =
  1512. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPanningHeight;
  1513. result->MemoryContent.ContentSize = sizeof (PRINTER_DATAA);
  1514. }
  1515. }
  1516. }
  1517. return result;
  1518. }
  1519. BOOL
  1520. FreeConvertedPrinterContent (
  1521. IN PMIG_CONTENT ObjectContent
  1522. )
  1523. {
  1524. if (!ObjectContent) {
  1525. return TRUE;
  1526. }
  1527. if (ObjectContent->MemoryContent.ContentBytes) {
  1528. IsmReleaseMemory (ObjectContent->MemoryContent.ContentBytes);
  1529. }
  1530. IsmReleaseMemory (ObjectContent);
  1531. return TRUE;
  1532. }