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.

1677 lines
66 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. if (Platform == PLATFORM_SOURCE) {
  364. printerTypeData.EnumFirstPhysicalObject = EnumFirstPrinter;
  365. printerTypeData.EnumNextPhysicalObject = EnumNextPrinter;
  366. printerTypeData.AbortEnumPhysicalObject = AbortEnumPrinter;
  367. printerTypeData.ConvertObjectToMultiSz = ConvertPrinterToMultiSz;
  368. printerTypeData.ConvertMultiSzToObject = ConvertMultiSzToPrinter;
  369. printerTypeData.GetNativeObjectName = GetNativePrinterName;
  370. printerTypeData.AcquirePhysicalObject = AcquirePrinter;
  371. printerTypeData.ReleasePhysicalObject = ReleasePrinter;
  372. printerTypeData.ConvertObjectContentToUnicode = ConvertPrinterContentToUnicode;
  373. printerTypeData.ConvertObjectContentToAnsi = ConvertPrinterContentToAnsi;
  374. printerTypeData.FreeConvertedObjectContent = FreeConvertedPrinterContent;
  375. g_PrinterTypeId = IsmRegisterObjectType (
  376. S_PRINTERS_NAME,
  377. TRUE,
  378. FALSE,
  379. &printerTypeData
  380. );
  381. } else {
  382. printerTypeData.EnumFirstPhysicalObject = EnumFirstPrinter;
  383. printerTypeData.EnumNextPhysicalObject = EnumNextPrinter;
  384. printerTypeData.AbortEnumPhysicalObject = AbortEnumPrinter;
  385. printerTypeData.ConvertObjectToMultiSz = ConvertPrinterToMultiSz;
  386. printerTypeData.ConvertMultiSzToObject = ConvertMultiSzToPrinter;
  387. printerTypeData.GetNativeObjectName = GetNativePrinterName;
  388. printerTypeData.AcquirePhysicalObject = AcquirePrinter;
  389. printerTypeData.ReleasePhysicalObject = ReleasePrinter;
  390. printerTypeData.DoesPhysicalObjectExist = DoesPrinterExist;
  391. printerTypeData.RemovePhysicalObject = RemovePrinter;
  392. printerTypeData.CreatePhysicalObject = CreatePrinter;
  393. printerTypeData.ReplacePhysicalObject = ReplacePrinter;
  394. printerTypeData.ConvertObjectContentToUnicode = ConvertPrinterContentToUnicode;
  395. printerTypeData.ConvertObjectContentToAnsi = ConvertPrinterContentToAnsi;
  396. printerTypeData.FreeConvertedObjectContent = FreeConvertedPrinterContent;
  397. g_PrinterTypeId = IsmRegisterObjectType (
  398. S_PRINTERS_NAME,
  399. TRUE,
  400. FALSE,
  401. &printerTypeData
  402. );
  403. }
  404. MYASSERT (g_PrinterTypeId);
  405. return TRUE;
  406. }
  407. VOID
  408. WINAPI
  409. PrintersEtmNewUserCreated (
  410. IN PCTSTR UserName,
  411. IN PCTSTR DomainName,
  412. IN PCTSTR UserProfileRoot,
  413. IN PSID UserSid
  414. )
  415. {
  416. // a new user was created, the printer operations need to be delayed
  417. PrintersTerminate ();
  418. g_DelayPrintersOp = TRUE;
  419. }
  420. BOOL
  421. WINAPI
  422. PrintersSgmInitialize (
  423. IN PMIG_LOGCALLBACK LogCallback,
  424. IN PVOID Reserved
  425. )
  426. {
  427. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  428. return TRUE;
  429. }
  430. BOOL
  431. WINAPI
  432. PrintersSgmParse (
  433. IN PVOID Reserved
  434. )
  435. {
  436. PCTSTR friendlyName;
  437. friendlyName = GetStringResource (MSG_PRINTERS_NAME);
  438. //IsmAddComponentAlias (
  439. // S_PRINTERS_NAME,
  440. // MASTERGROUP_SYSTEM,
  441. // friendlyName,
  442. // COMPONENT_NAME,
  443. // FALSE
  444. // );
  445. IsmAddComponentAlias (
  446. S_CORPNET_NAME,
  447. MASTERGROUP_SYSTEM,
  448. friendlyName,
  449. COMPONENT_NAME,
  450. FALSE
  451. );
  452. FreeStringResource (friendlyName);
  453. return TRUE;
  454. }
  455. UINT
  456. SgmPrintersCallback (
  457. IN PCMIG_OBJECTENUMDATA Data,
  458. IN ULONG_PTR CallerArg
  459. )
  460. {
  461. IsmAbandonObjectOnCollision (Data->ObjectTypeId, Data->ObjectName);
  462. IsmMakeApplyObject (Data->ObjectTypeId, Data->ObjectName);
  463. return CALLBACK_ENUM_CONTINUE;
  464. }
  465. BOOL
  466. WINAPI
  467. PrintersSgmQueueEnumeration (
  468. IN PVOID Reserved
  469. )
  470. {
  471. ENCODEDSTRHANDLE pattern;
  472. if (!IsmIsComponentSelected (S_PRINTERS_NAME, 0) &&
  473. !IsmIsComponentSelected (S_CORPNET_NAME, 0)
  474. ) {
  475. g_PrinterMigEnabled = FALSE;
  476. return TRUE;
  477. }
  478. g_PrinterMigEnabled = TRUE;
  479. pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, FALSE);
  480. IsmQueueEnumeration (
  481. g_PrinterTypeId,
  482. pattern,
  483. SgmPrintersCallback,
  484. (ULONG_PTR) 0,
  485. S_PRINTERS_NAME
  486. );
  487. IsmDestroyObjectHandle (pattern);
  488. return TRUE;
  489. }
  490. BOOL
  491. WINAPI
  492. PrintersVcmInitialize (
  493. IN PMIG_LOGCALLBACK LogCallback,
  494. IN PVOID Reserved
  495. )
  496. {
  497. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  498. return TRUE;
  499. }
  500. BOOL
  501. WINAPI
  502. PrintersVcmParse (
  503. IN PVOID Reserved
  504. )
  505. {
  506. return PrintersSgmParse (Reserved);
  507. }
  508. UINT
  509. VcmPrintersCallback (
  510. IN PCMIG_OBJECTENUMDATA Data,
  511. IN ULONG_PTR CallerArg
  512. )
  513. {
  514. IsmMakePersistentObject (Data->ObjectTypeId, Data->ObjectName);
  515. return CALLBACK_ENUM_CONTINUE;
  516. }
  517. BOOL
  518. WINAPI
  519. PrintersVcmQueueEnumeration (
  520. IN PVOID Reserved
  521. )
  522. {
  523. ENCODEDSTRHANDLE pattern;
  524. if (!IsmIsComponentSelected (S_PRINTERS_NAME, 0) &&
  525. !IsmIsComponentSelected (S_CORPNET_NAME, 0)
  526. ) {
  527. g_PrinterMigEnabled = FALSE;
  528. return TRUE;
  529. }
  530. g_PrinterMigEnabled = TRUE;
  531. pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, FALSE);
  532. IsmQueueEnumeration (
  533. g_PrinterTypeId,
  534. pattern,
  535. VcmPrintersCallback,
  536. (ULONG_PTR) 0,
  537. S_PRINTERS_NAME
  538. );
  539. IsmDestroyObjectHandle (pattern);
  540. return TRUE;
  541. }
  542. BOOL
  543. pEnumPrinterWorker (
  544. OUT PMIG_TYPEOBJECTENUM EnumPtr,
  545. IN PPRINTER_ENUM PrinterEnum
  546. )
  547. {
  548. if (EnumPtr->ObjectNode) {
  549. IsmDestroyObjectString (EnumPtr->ObjectNode);
  550. EnumPtr->ObjectNode = NULL;
  551. }
  552. if (EnumPtr->ObjectLeaf) {
  553. IsmDestroyObjectString (EnumPtr->ObjectLeaf);
  554. EnumPtr->ObjectLeaf = NULL;
  555. }
  556. do {
  557. EnumPtr->ObjectName = IsmCreateObjectHandle (PrinterEnum->HashData.String, NULL);
  558. if (!ObsPatternMatch (PrinterEnum->Pattern, EnumPtr->ObjectName)) {
  559. if (!EnumNextHashTableString (&PrinterEnum->HashData)) {
  560. AbortEnumPrinter (EnumPtr);
  561. return FALSE;
  562. }
  563. continue;
  564. }
  565. EnumPtr->NativeObjectName = PrinterEnum->HashData.String;
  566. IsmCreateObjectStringsFromHandle (EnumPtr->ObjectName, &EnumPtr->ObjectNode, &EnumPtr->ObjectLeaf);
  567. EnumPtr->Level = 1;
  568. EnumPtr->SubLevel = 0;
  569. EnumPtr->IsLeaf = FALSE;
  570. EnumPtr->IsNode = TRUE;
  571. EnumPtr->Details.DetailsSize = 0;
  572. EnumPtr->Details.DetailsData = NULL;
  573. return TRUE;
  574. } while (TRUE);
  575. }
  576. BOOL
  577. EnumFirstPrinter (
  578. IN OUT PMIG_TYPEOBJECTENUM EnumPtr, CALLER_INITIALIZED
  579. IN MIG_OBJECTSTRINGHANDLE Pattern,
  580. IN UINT MaxLevel
  581. )
  582. {
  583. PPRINTER_ENUM printerEnum = NULL;
  584. if (!g_PrintersTable) {
  585. return FALSE;
  586. }
  587. printerEnum = (PPRINTER_ENUM) PmGetMemory (g_PrintersPool, sizeof (PRINTER_ENUM));
  588. printerEnum->Pattern = PmDuplicateString (g_PrintersPool, Pattern);
  589. EnumPtr->EtmHandle = (LONG_PTR) printerEnum;
  590. if (EnumFirstHashTableString (&printerEnum->HashData, g_PrintersTable)) {
  591. return pEnumPrinterWorker (EnumPtr, printerEnum);
  592. } else {
  593. AbortEnumPrinter (EnumPtr);
  594. return FALSE;
  595. }
  596. }
  597. BOOL
  598. EnumNextPrinter (
  599. IN OUT PMIG_TYPEOBJECTENUM EnumPtr
  600. )
  601. {
  602. PPRINTER_ENUM printerEnum = NULL;
  603. if (EnumPtr->ObjectName) {
  604. IsmDestroyObjectHandle (EnumPtr->ObjectName);
  605. EnumPtr->ObjectName = NULL;
  606. }
  607. printerEnum = (PPRINTER_ENUM)(EnumPtr->EtmHandle);
  608. if (!printerEnum) {
  609. return FALSE;
  610. }
  611. if (EnumNextHashTableString (&printerEnum->HashData)) {
  612. return pEnumPrinterWorker (EnumPtr, printerEnum);
  613. } else {
  614. AbortEnumPrinter (EnumPtr);
  615. return FALSE;
  616. }
  617. }
  618. VOID
  619. AbortEnumPrinter (
  620. IN OUT PMIG_TYPEOBJECTENUM EnumPtr
  621. )
  622. {
  623. PPRINTER_ENUM printerEnum = NULL;
  624. if (EnumPtr->ObjectName) {
  625. IsmDestroyObjectHandle (EnumPtr->ObjectName);
  626. EnumPtr->ObjectName = NULL;
  627. }
  628. if (EnumPtr->ObjectNode) {
  629. IsmDestroyObjectString (EnumPtr->ObjectNode);
  630. EnumPtr->ObjectNode = NULL;
  631. }
  632. if (EnumPtr->ObjectLeaf) {
  633. IsmDestroyObjectString (EnumPtr->ObjectLeaf);
  634. EnumPtr->ObjectLeaf = NULL;
  635. }
  636. printerEnum = (PPRINTER_ENUM)(EnumPtr->EtmHandle);
  637. if (!printerEnum) {
  638. return;
  639. }
  640. PmReleaseMemory (g_PrintersPool, printerEnum->Pattern);
  641. PmReleaseMemory (g_PrintersPool, printerEnum);
  642. ZeroMemory (EnumPtr, sizeof (MIG_TYPEOBJECTENUM));
  643. }
  644. BOOL
  645. AcquirePrinter (
  646. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  647. OUT PMIG_CONTENT ObjectContent, CALLER_INITIALIZED
  648. IN MIG_CONTENTTYPE ContentType,
  649. IN UINT MemoryContentLimit
  650. )
  651. {
  652. PCTSTR node;
  653. PCTSTR leaf;
  654. PPRINTER_DATA printerData = NULL;
  655. BOOL result = FALSE;
  656. if (!ObjectContent) {
  657. return FALSE;
  658. }
  659. if (ContentType == CONTENTTYPE_FILE) {
  660. // nobody should request this as a file
  661. MYASSERT (FALSE);
  662. return FALSE;
  663. }
  664. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  665. if (HtFindStringEx (g_PrintersTable, node, (PVOID)(&printerData), FALSE)) {
  666. ObjectContent->MemoryContent.ContentBytes = (PCBYTE)printerData;
  667. ObjectContent->MemoryContent.ContentSize = sizeof (PRINTER_DATA);
  668. result = TRUE;
  669. }
  670. IsmDestroyObjectString (node);
  671. IsmDestroyObjectString (leaf);
  672. }
  673. return result;
  674. }
  675. BOOL
  676. ReleasePrinter (
  677. IN OUT PMIG_CONTENT ObjectContent
  678. )
  679. {
  680. if (ObjectContent) {
  681. ZeroMemory (ObjectContent, sizeof (MIG_CONTENT));
  682. }
  683. return TRUE;
  684. }
  685. BOOL
  686. DoesPrinterExist (
  687. IN MIG_OBJECTSTRINGHANDLE ObjectName
  688. )
  689. {
  690. PCTSTR node;
  691. PCTSTR leaf;
  692. PPRINTER_DATA printerData = NULL;
  693. BOOL result = FALSE;
  694. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  695. if (g_PrintersTable &&
  696. HtFindStringEx (g_PrintersTable, node, (PVOID)(&printerData), FALSE)
  697. ) {
  698. result = TRUE;
  699. }
  700. IsmDestroyObjectString (node);
  701. IsmDestroyObjectString (leaf);
  702. }
  703. return result;
  704. }
  705. BOOL
  706. RemovePrinter (
  707. IN MIG_OBJECTSTRINGHANDLE ObjectName
  708. )
  709. {
  710. PCTSTR node;
  711. PCTSTR leaf;
  712. BOOL result = FALSE;
  713. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  714. if (node && (!leaf)) {
  715. result = DeletePrinterConnection ((PTSTR)node);
  716. }
  717. IsmDestroyObjectString (node);
  718. IsmDestroyObjectString (leaf);
  719. }
  720. return result;
  721. }
  722. BOOL
  723. CreatePrinter (
  724. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  725. IN PMIG_CONTENT ObjectContent
  726. )
  727. {
  728. PCTSTR node;
  729. PCTSTR leaf;
  730. PPRINTER_DATA printerData;
  731. HANDLE printerHandle = NULL;
  732. BOOL result = FALSE;
  733. UINT devModeSize;
  734. PPRINTER_INFO_2 printerInfo;
  735. UINT printerInfoSize;
  736. PDEVMODE devMode;
  737. if (!ObjectContent->ContentInFile) {
  738. if (ObjectContent->MemoryContent.ContentBytes && ObjectContent->MemoryContent.ContentSize) {
  739. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  740. if (node && (!leaf)) {
  741. if (g_DelayPrintersOp) {
  742. // we need to delay this operation
  743. // record delayed printer replace operation
  744. IsmRecordDelayedOperation (
  745. JRNOP_CREATE,
  746. g_PrinterTypeId,
  747. ObjectName,
  748. ObjectContent
  749. );
  750. result = TRUE;
  751. } else {
  752. // record printer creation
  753. IsmRecordOperation (
  754. JRNOP_CREATE,
  755. g_PrinterTypeId,
  756. ObjectName
  757. );
  758. result = AddPrinterConnection ((PTSTR)node);
  759. if (result) {
  760. printerData = (PPRINTER_DATA)(ObjectContent->MemoryContent.ContentBytes);
  761. if (printerData->dmFields) {
  762. // let's restore printer settings
  763. if (OpenPrinter ((PTSTR)node, &printerHandle, NULL)) {
  764. if (GetPrinter (printerHandle, 2, 0, 0, &printerInfoSize) || (GetLastError () == ERROR_INSUFFICIENT_BUFFER)) {
  765. printerInfo = PmGetMemory (g_PrintersPool, (printerInfoSize > sizeof (PRINTER_INFO_2))?printerInfoSize:sizeof (PRINTER_INFO_2));
  766. ZeroMemory (printerInfo, (printerInfoSize > sizeof (PRINTER_INFO_2))?printerInfoSize:sizeof (PRINTER_INFO_2));
  767. if (GetPrinter (printerHandle, 2, (PBYTE)printerInfo, printerInfoSize, &printerInfoSize)) {
  768. if (printerInfo->pDevMode) {
  769. devMode = printerInfo->pDevMode;
  770. } else {
  771. devModeSize = DocumentProperties (NULL, printerHandle, (PTSTR)node, NULL, NULL, 0);
  772. if (devModeSize) {
  773. devMode = PmGetMemory (g_PrintersPool, (devModeSize > sizeof (DEVMODE))?devModeSize:sizeof (DEVMODE));
  774. if (!DocumentProperties (NULL, printerHandle, (PTSTR)node, devMode, NULL, DM_OUT_BUFFER) == IDOK) {
  775. PmReleaseMemory (g_PrintersPool, devMode);
  776. devMode = NULL;
  777. } else {
  778. printerInfo->pDevMode = devMode;
  779. }
  780. }
  781. }
  782. if (devMode) {
  783. if ((devMode->dmFields & DM_ORIENTATION) && (printerData->dmFields & DM_ORIENTATION)) {
  784. devMode->dmOrientation = printerData->dmOrientation;
  785. }
  786. if ((devMode->dmFields & DM_PAPERSIZE) && (printerData->dmFields & DM_PAPERSIZE)) {
  787. devMode->dmPaperSize = printerData->dmPaperSize;
  788. }
  789. if ((devMode->dmFields & DM_PAPERLENGTH) && (printerData->dmFields & DM_PAPERLENGTH)) {
  790. devMode->dmPaperLength = printerData->dmPaperLength;
  791. }
  792. if ((devMode->dmFields & DM_PAPERWIDTH) && (printerData->dmFields & DM_PAPERWIDTH)) {
  793. devMode->dmPaperWidth = printerData->dmPaperWidth;
  794. }
  795. if ((devMode->dmFields & DM_SCALE) && (printerData->dmFields & DM_SCALE)) {
  796. devMode->dmScale = printerData->dmScale;
  797. }
  798. if ((devMode->dmFields & DM_POSITION) && (printerData->dmFields & DM_POSITION)) {
  799. CopyMemory (&devMode->dmScale, &printerData->dmScale, sizeof(POINTL));
  800. }
  801. if ((devMode->dmFields & DM_NUP) && (printerData->dmFields & DM_NUP)) {
  802. devMode->dmNup = printerData->dmNup;
  803. }
  804. if ((devMode->dmFields & DM_COPIES) && (printerData->dmFields & DM_COPIES)) {
  805. devMode->dmCopies = printerData->dmCopies;
  806. }
  807. if ((devMode->dmFields & DM_DEFAULTSOURCE) && (printerData->dmFields & DM_DEFAULTSOURCE)) {
  808. devMode->dmDefaultSource = printerData->dmDefaultSource;
  809. }
  810. if ((devMode->dmFields & DM_PRINTQUALITY) && (printerData->dmFields & DM_PRINTQUALITY)) {
  811. devMode->dmPrintQuality = printerData->dmPrintQuality;
  812. }
  813. if ((devMode->dmFields & DM_COLOR) && (printerData->dmFields & DM_COLOR)) {
  814. devMode->dmColor = printerData->dmColor;
  815. }
  816. if ((devMode->dmFields & DM_DUPLEX) && (printerData->dmFields & DM_DUPLEX)) {
  817. devMode->dmDuplex = printerData->dmDuplex;
  818. }
  819. if ((devMode->dmFields & DM_YRESOLUTION) && (printerData->dmFields & DM_YRESOLUTION)) {
  820. devMode->dmYResolution = printerData->dmYResolution;
  821. }
  822. if ((devMode->dmFields & DM_TTOPTION) && (printerData->dmFields & DM_TTOPTION)) {
  823. devMode->dmTTOption = printerData->dmTTOption;
  824. }
  825. if ((devMode->dmFields & DM_COLLATE) && (printerData->dmFields & DM_COLLATE)) {
  826. devMode->dmCollate = printerData->dmCollate;
  827. }
  828. if ((devMode->dmFields & DM_FORMNAME) && (printerData->dmFields & DM_FORMNAME)) {
  829. CopyMemory (devMode->dmFormName, printerData->dmFormName, sizeof (devMode->dmFormName));
  830. }
  831. if ((devMode->dmFields & DM_LOGPIXELS) && (printerData->dmFields & DM_LOGPIXELS)) {
  832. devMode->dmLogPixels = printerData->dmLogPixels;
  833. }
  834. if ((devMode->dmFields & DM_BITSPERPEL) && (printerData->dmFields & DM_BITSPERPEL)) {
  835. devMode->dmBitsPerPel = printerData->dmBitsPerPel;
  836. }
  837. if ((devMode->dmFields & DM_PELSWIDTH) && (printerData->dmFields & DM_PELSWIDTH)) {
  838. devMode->dmPelsWidth = printerData->dmPelsWidth;
  839. }
  840. if ((devMode->dmFields & DM_PELSHEIGHT) && (printerData->dmFields & DM_PELSHEIGHT)) {
  841. devMode->dmPelsHeight = printerData->dmPelsHeight;
  842. }
  843. if ((devMode->dmFields & DM_DISPLAYFLAGS) && (printerData->dmFields & DM_DISPLAYFLAGS)) {
  844. devMode->dmDisplayFlags = printerData->dmDisplayFlags;
  845. }
  846. if ((devMode->dmFields & DM_DISPLAYFREQUENCY) && (printerData->dmFields & DM_DISPLAYFREQUENCY)) {
  847. devMode->dmDisplayFrequency = printerData->dmDisplayFrequency;
  848. }
  849. if ((devMode->dmFields & DM_ICMMETHOD) && (printerData->dmFields & DM_ICMMETHOD)) {
  850. devMode->dmICMMethod = printerData->dmICMMethod;
  851. }
  852. if ((devMode->dmFields & DM_ICMINTENT) && (printerData->dmFields & DM_ICMINTENT)) {
  853. devMode->dmICMIntent = printerData->dmICMIntent;
  854. }
  855. if ((devMode->dmFields & DM_MEDIATYPE) && (printerData->dmFields & DM_MEDIATYPE)) {
  856. devMode->dmMediaType = printerData->dmMediaType;
  857. }
  858. if ((devMode->dmFields & DM_DITHERTYPE) && (printerData->dmFields & DM_DITHERTYPE)) {
  859. devMode->dmDitherType = printerData->dmDitherType;
  860. }
  861. if ((devMode->dmFields & DM_PANNINGWIDTH) && (printerData->dmFields & DM_PANNINGWIDTH)) {
  862. devMode->dmPanningWidth = printerData->dmPanningWidth;
  863. }
  864. if ((devMode->dmFields & DM_PANNINGHEIGHT) && (printerData->dmFields & DM_PANNINGHEIGHT)) {
  865. devMode->dmPanningHeight = printerData->dmPanningHeight;
  866. }
  867. if (DocumentProperties (NULL, printerHandle, (PTSTR)node, devMode, devMode, DM_IN_BUFFER | DM_OUT_BUFFER) == IDOK) {
  868. SetPrinter (printerHandle, 2, (PBYTE)printerInfo, 0);
  869. } else {
  870. DEBUGMSG ((DBG_PRINTERS, "Failed to restore printer %s settings", node));
  871. }
  872. if (devMode != printerInfo->pDevMode) {
  873. PmReleaseMemory (g_PrintersPool, devMode);
  874. }
  875. } else {
  876. DEBUGMSG ((DBG_PRINTERS, "Failed to restore printer %s settings", node));
  877. }
  878. } else {
  879. DEBUGMSG ((DBG_PRINTERS, "Failed to restore printer %s settings", node));
  880. }
  881. PmReleaseMemory (g_PrintersPool, printerInfo);
  882. } else {
  883. DEBUGMSG ((DBG_PRINTERS, "Failed to restore printer %s settings", node));
  884. }
  885. ClosePrinter (printerHandle);
  886. } else {
  887. DEBUGMSG ((DBG_PRINTERS, "Failed to restore printer %s settings", node));
  888. }
  889. }
  890. if (printerData && printerData->Default) {
  891. result = SetDefaultPrinter (node);
  892. if (!result) {
  893. DEBUGMSG ((DBG_PRINTERS, "Failed to set %s as default printer", node));
  894. }
  895. }
  896. } else {
  897. DEBUGMSG ((DBG_PRINTERS, "Failed to add printer connection for %s", node));
  898. }
  899. }
  900. }
  901. IsmDestroyObjectString (node);
  902. IsmDestroyObjectString (leaf);
  903. }
  904. }
  905. }
  906. return result;
  907. }
  908. BOOL
  909. ReplacePrinter (
  910. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  911. IN PMIG_CONTENT ObjectContent
  912. )
  913. {
  914. BOOL result = TRUE;
  915. if (g_DelayPrintersOp) {
  916. // we need to delay this operation
  917. // record delayed printer replace operation
  918. IsmRecordDelayedOperation (
  919. JRNOP_REPLACE,
  920. g_PrinterTypeId,
  921. ObjectName,
  922. ObjectContent
  923. );
  924. result = TRUE;
  925. } else {
  926. // we are going to delete any existing printers with this name,
  927. // and create a new one
  928. if (DoesPrinterExist (ObjectName)) {
  929. result = RemovePrinter (ObjectName);
  930. }
  931. if (result) {
  932. result = CreatePrinter (ObjectName, ObjectContent);
  933. }
  934. }
  935. return result;
  936. }
  937. PCTSTR
  938. ConvertPrinterToMultiSz (
  939. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  940. IN PMIG_CONTENT ObjectContent
  941. )
  942. {
  943. PCTSTR node, leaf;
  944. PTSTR result = NULL;
  945. BOOL bresult = TRUE;
  946. PPRINTER_DATA printerData;
  947. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  948. MYASSERT (!leaf);
  949. g_PrinterConversionBuff.End = 0;
  950. GbCopyQuotedString (&g_PrinterConversionBuff, node);
  951. MYASSERT (ObjectContent->Details.DetailsSize == 0);
  952. MYASSERT (!ObjectContent->ContentInFile);
  953. MYASSERT (ObjectContent->MemoryContent.ContentSize = sizeof (PRINTER_DATA));
  954. if ((!ObjectContent->ContentInFile) &&
  955. (ObjectContent->MemoryContent.ContentSize) &&
  956. (ObjectContent->MemoryContent.ContentSize == sizeof (PRINTER_DATA)) &&
  957. (ObjectContent->MemoryContent.ContentBytes)
  958. ) {
  959. printerData = (PPRINTER_DATA)ObjectContent->MemoryContent.ContentBytes;
  960. wsprintf (
  961. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  962. TEXT("0x%08X"),
  963. printerData->Default
  964. );
  965. wsprintf (
  966. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  967. TEXT("0x%08X"),
  968. printerData->dmFields
  969. );
  970. wsprintf (
  971. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  972. TEXT("0x%08X"),
  973. printerData->dmOrientation
  974. );
  975. wsprintf (
  976. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  977. TEXT("0x%08X"),
  978. printerData->dmPaperSize
  979. );
  980. wsprintf (
  981. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  982. TEXT("0x%08X"),
  983. printerData->dmPaperLength
  984. );
  985. wsprintf (
  986. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  987. TEXT("0x%08X"),
  988. printerData->dmPaperWidth
  989. );
  990. wsprintf (
  991. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  992. TEXT("0x%08X"),
  993. printerData->dmPosition.x
  994. );
  995. wsprintf (
  996. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  997. TEXT("0x%08X"),
  998. printerData->dmPosition.y
  999. );
  1000. wsprintf (
  1001. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1002. TEXT("0x%08X"),
  1003. printerData->dmScale
  1004. );
  1005. wsprintf (
  1006. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1007. TEXT("0x%08X"),
  1008. printerData->dmCopies
  1009. );
  1010. wsprintf (
  1011. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1012. TEXT("0x%08X"),
  1013. printerData->dmDefaultSource
  1014. );
  1015. wsprintf (
  1016. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1017. TEXT("0x%08X"),
  1018. printerData->dmPrintQuality
  1019. );
  1020. wsprintf (
  1021. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1022. TEXT("0x%08X"),
  1023. printerData->dmColor
  1024. );
  1025. wsprintf (
  1026. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1027. TEXT("0x%08X"),
  1028. printerData->dmDuplex
  1029. );
  1030. wsprintf (
  1031. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1032. TEXT("0x%08X"),
  1033. printerData->dmYResolution
  1034. );
  1035. wsprintf (
  1036. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1037. TEXT("0x%08X"),
  1038. printerData->dmTTOption
  1039. );
  1040. wsprintf (
  1041. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1042. TEXT("0x%08X"),
  1043. printerData->dmCollate
  1044. );
  1045. GbCopyQuotedString (&g_PrinterConversionBuff, printerData->dmFormName);
  1046. wsprintf (
  1047. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1048. TEXT("0x%08X"),
  1049. printerData->dmLogPixels
  1050. );
  1051. wsprintf (
  1052. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1053. TEXT("0x%08X"),
  1054. printerData->dmBitsPerPel
  1055. );
  1056. wsprintf (
  1057. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1058. TEXT("0x%08X"),
  1059. printerData->dmPelsWidth
  1060. );
  1061. wsprintf (
  1062. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1063. TEXT("0x%08X"),
  1064. printerData->dmPelsHeight
  1065. );
  1066. wsprintf (
  1067. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1068. TEXT("0x%08X"),
  1069. printerData->dmDisplayFlags
  1070. );
  1071. wsprintf (
  1072. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1073. TEXT("0x%08X"),
  1074. printerData->dmNup
  1075. );
  1076. wsprintf (
  1077. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1078. TEXT("0x%08X"),
  1079. printerData->dmDisplayFrequency
  1080. );
  1081. wsprintf (
  1082. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1083. TEXT("0x%08X"),
  1084. printerData->dmICMMethod
  1085. );
  1086. wsprintf (
  1087. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1088. TEXT("0x%08X"),
  1089. printerData->dmICMIntent
  1090. );
  1091. wsprintf (
  1092. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1093. TEXT("0x%08X"),
  1094. printerData->dmMediaType
  1095. );
  1096. wsprintf (
  1097. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1098. TEXT("0x%08X"),
  1099. printerData->dmDitherType
  1100. );
  1101. wsprintf (
  1102. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1103. TEXT("0x%08X"),
  1104. printerData->dmPanningWidth
  1105. );
  1106. wsprintf (
  1107. (PTSTR) GbGrow (&g_PrinterConversionBuff, (sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)),
  1108. TEXT("0x%08X"),
  1109. printerData->dmPanningHeight
  1110. );
  1111. } else {
  1112. bresult = FALSE;
  1113. }
  1114. if (bresult) {
  1115. GbCopyString (&g_PrinterConversionBuff, TEXT(""));
  1116. result = IsmGetMemory (g_PrinterConversionBuff.End);
  1117. CopyMemory (result, g_PrinterConversionBuff.Buf, g_PrinterConversionBuff.End);
  1118. }
  1119. g_PrinterConversionBuff.End = 0;
  1120. IsmDestroyObjectString (node);
  1121. IsmDestroyObjectString (leaf);
  1122. }
  1123. return result;
  1124. }
  1125. BOOL
  1126. ConvertMultiSzToPrinter (
  1127. IN PCTSTR ObjectMultiSz,
  1128. OUT MIG_OBJECTSTRINGHANDLE *ObjectName,
  1129. OUT PMIG_CONTENT ObjectContent OPTIONAL
  1130. )
  1131. {
  1132. MULTISZ_ENUM multiSzEnum;
  1133. PCTSTR name = NULL;
  1134. PRINTER_DATA printerData;
  1135. DWORD dummy;
  1136. UINT index;
  1137. g_PrinterConversionBuff.End = 0;
  1138. ZeroMemory (&printerData, sizeof (PRINTER_DATA));
  1139. if (EnumFirstMultiSz (&multiSzEnum, ObjectMultiSz)) {
  1140. index = 0;
  1141. do {
  1142. if (index == 0) {
  1143. name = multiSzEnum.CurrentString;
  1144. }
  1145. if (index == 1) {
  1146. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1147. printerData.Default = dummy;
  1148. }
  1149. if (index == 2) {
  1150. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1151. printerData.dmFields = dummy;
  1152. }
  1153. if (index == 3) {
  1154. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1155. printerData.dmOrientation = (SHORT)dummy;
  1156. }
  1157. if (index == 4) {
  1158. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1159. printerData.dmPaperSize = (SHORT)dummy;
  1160. }
  1161. if (index == 5) {
  1162. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1163. printerData.dmPaperLength = (SHORT)dummy;
  1164. }
  1165. if (index == 6) {
  1166. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1167. printerData.dmPaperWidth = (SHORT)dummy;
  1168. }
  1169. if (index == 7) {
  1170. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1171. printerData.dmPosition.x = dummy;
  1172. }
  1173. if (index == 8) {
  1174. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1175. printerData.dmPosition.y = dummy;
  1176. }
  1177. if (index == 9) {
  1178. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1179. printerData.dmScale = (SHORT)dummy;
  1180. }
  1181. if (index == 10) {
  1182. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1183. printerData.dmCopies = (SHORT)dummy;
  1184. }
  1185. if (index == 11) {
  1186. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1187. printerData.dmDefaultSource = (SHORT)dummy;
  1188. }
  1189. if (index == 12) {
  1190. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1191. printerData.dmPrintQuality = (SHORT)dummy;
  1192. }
  1193. if (index == 13) {
  1194. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1195. printerData.dmColor = (SHORT)dummy;
  1196. }
  1197. if (index == 14) {
  1198. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1199. printerData.dmDuplex = (SHORT)dummy;
  1200. }
  1201. if (index == 15) {
  1202. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1203. printerData.dmYResolution = (SHORT)dummy;
  1204. }
  1205. if (index == 16) {
  1206. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1207. printerData.dmTTOption = (SHORT)dummy;
  1208. }
  1209. if (index == 17) {
  1210. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1211. printerData.dmCollate = (SHORT)dummy;
  1212. }
  1213. if (index == 18) {
  1214. if (!StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
  1215. StringCopyTcharCount (printerData.dmFormName, multiSzEnum.CurrentString, CCHFORMNAME);
  1216. }
  1217. }
  1218. if (index == 19) {
  1219. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1220. printerData.dmLogPixels = (WORD)dummy;
  1221. }
  1222. if (index == 20) {
  1223. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1224. printerData.dmBitsPerPel = dummy;
  1225. }
  1226. if (index == 21) {
  1227. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1228. printerData.dmPelsWidth = dummy;
  1229. }
  1230. if (index == 22) {
  1231. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1232. printerData.dmPelsHeight = dummy;
  1233. }
  1234. if (index == 23) {
  1235. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1236. printerData.dmDisplayFlags = dummy;
  1237. }
  1238. if (index == 24) {
  1239. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1240. printerData.dmNup = dummy;
  1241. }
  1242. if (index == 25) {
  1243. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1244. printerData.dmDisplayFrequency = dummy;
  1245. }
  1246. if (index == 26) {
  1247. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1248. printerData.dmICMMethod = dummy;
  1249. }
  1250. if (index == 27) {
  1251. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1252. printerData.dmICMIntent = dummy;
  1253. }
  1254. if (index == 28) {
  1255. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1256. printerData.dmMediaType = dummy;
  1257. }
  1258. if (index == 29) {
  1259. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1260. printerData.dmDitherType = dummy;
  1261. }
  1262. if (index == 30) {
  1263. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1264. printerData.dmPanningWidth = dummy;
  1265. }
  1266. if (index == 31) {
  1267. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &dummy);
  1268. printerData.dmPanningHeight = dummy;
  1269. }
  1270. index ++;
  1271. } while (EnumNextMultiSz (&multiSzEnum));
  1272. }
  1273. if (!name) {
  1274. return FALSE;
  1275. }
  1276. if (ObjectContent) {
  1277. ObjectContent->ContentInFile = FALSE;
  1278. ObjectContent->MemoryContent.ContentSize = sizeof (PRINTER_DATA);
  1279. ObjectContent->MemoryContent.ContentBytes = IsmGetMemory (ObjectContent->MemoryContent.ContentSize);
  1280. CopyMemory (
  1281. (PBYTE)ObjectContent->MemoryContent.ContentBytes,
  1282. &printerData,
  1283. ObjectContent->MemoryContent.ContentSize
  1284. );
  1285. ObjectContent->Details.DetailsSize = 0;
  1286. ObjectContent->Details.DetailsData = NULL;
  1287. }
  1288. *ObjectName = IsmCreateObjectHandle (name, NULL);
  1289. return TRUE;
  1290. }
  1291. PCTSTR
  1292. GetNativePrinterName (
  1293. IN MIG_OBJECTSTRINGHANDLE ObjectName
  1294. )
  1295. {
  1296. PCTSTR node, leaf;
  1297. PTSTR nodePtr = NULL, nodeBegin = NULL;
  1298. UINT strSize = 0;
  1299. PTSTR result = NULL;
  1300. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  1301. if (node) {
  1302. nodePtr = _tcsrchr (node, TEXT('\\'));
  1303. if (nodePtr) {
  1304. *nodePtr = 0;
  1305. nodePtr ++;
  1306. }
  1307. nodeBegin = (PTSTR)node;
  1308. while (*nodeBegin == TEXT('\\')) {
  1309. nodeBegin ++;
  1310. }
  1311. if (nodePtr) {
  1312. strSize = CharCount (nodePtr) + \
  1313. CharCount (TEXT(" on ")) + \
  1314. CharCount (nodeBegin) + \
  1315. 1;
  1316. result = IsmGetMemory (strSize * sizeof (TCHAR));
  1317. _tcscpy (result, nodePtr);
  1318. _tcscat (result, TEXT(" on "));
  1319. _tcscat (result, nodeBegin);
  1320. } else {
  1321. strSize = CharCount (nodeBegin) + \
  1322. 1;
  1323. result = IsmGetMemory (strSize * sizeof (TCHAR));
  1324. _tcscpy (result, nodeBegin);
  1325. }
  1326. }
  1327. IsmDestroyObjectString (node);
  1328. IsmDestroyObjectString (leaf);
  1329. }
  1330. return result;
  1331. }
  1332. PMIG_CONTENT
  1333. ConvertPrinterContentToUnicode (
  1334. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1335. IN PMIG_CONTENT ObjectContent
  1336. )
  1337. {
  1338. PMIG_CONTENT result = NULL;
  1339. if (!ObjectContent) {
  1340. return result;
  1341. }
  1342. if (ObjectContent->ContentInFile) {
  1343. return result;
  1344. }
  1345. result = IsmGetMemory (sizeof (MIG_CONTENT));
  1346. if (result) {
  1347. CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
  1348. if ((ObjectContent->MemoryContent.ContentSize != 0) &&
  1349. (ObjectContent->MemoryContent.ContentBytes != NULL)
  1350. ) {
  1351. // convert Printer content
  1352. result->MemoryContent.ContentBytes = IsmGetMemory (sizeof (PRINTER_DATAW));
  1353. if (result->MemoryContent.ContentBytes) {
  1354. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->Default =
  1355. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->Default;
  1356. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmFields =
  1357. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmFields;
  1358. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmOrientation =
  1359. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmOrientation;
  1360. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPaperSize =
  1361. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPaperSize;
  1362. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPaperLength =
  1363. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPaperLength;
  1364. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPaperWidth =
  1365. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPaperWidth;
  1366. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPosition.x =
  1367. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPosition.x;
  1368. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPosition.y =
  1369. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPosition.y;
  1370. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmScale =
  1371. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmScale;
  1372. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmCopies =
  1373. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmCopies;
  1374. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmDefaultSource =
  1375. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmDefaultSource;
  1376. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPrintQuality =
  1377. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPrintQuality;
  1378. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmColor =
  1379. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmColor;
  1380. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmDuplex =
  1381. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmDuplex;
  1382. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmYResolution =
  1383. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmYResolution;
  1384. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmTTOption =
  1385. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmTTOption;
  1386. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmCollate =
  1387. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmCollate;
  1388. DirectDbcsToUnicodeN (
  1389. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmFormName,
  1390. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmFormName,
  1391. CCHFORMNAME
  1392. );
  1393. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmLogPixels =
  1394. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmLogPixels;
  1395. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmBitsPerPel =
  1396. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmBitsPerPel;
  1397. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPelsWidth =
  1398. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPelsWidth;
  1399. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPelsHeight =
  1400. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPelsHeight;
  1401. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmDisplayFlags =
  1402. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmDisplayFlags;
  1403. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmNup =
  1404. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmNup;
  1405. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmDisplayFrequency =
  1406. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmDisplayFrequency;
  1407. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmICMMethod =
  1408. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmICMMethod;
  1409. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmICMIntent =
  1410. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmICMIntent;
  1411. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmMediaType =
  1412. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmMediaType;
  1413. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmDitherType =
  1414. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmDitherType;
  1415. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPanningWidth =
  1416. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPanningWidth;
  1417. ((PPRINTER_DATAW)result->MemoryContent.ContentBytes)->dmPanningHeight =
  1418. ((PPRINTER_DATAA)ObjectContent->MemoryContent.ContentBytes)->dmPanningHeight;
  1419. result->MemoryContent.ContentSize = sizeof (PRINTER_DATAW);
  1420. }
  1421. }
  1422. }
  1423. return result;
  1424. }
  1425. PMIG_CONTENT
  1426. ConvertPrinterContentToAnsi (
  1427. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1428. IN PMIG_CONTENT ObjectContent
  1429. )
  1430. {
  1431. PMIG_CONTENT result = NULL;
  1432. if (!ObjectContent) {
  1433. return result;
  1434. }
  1435. if (ObjectContent->ContentInFile) {
  1436. return result;
  1437. }
  1438. result = IsmGetMemory (sizeof (MIG_CONTENT));
  1439. if (result) {
  1440. CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
  1441. if ((ObjectContent->MemoryContent.ContentSize != 0) &&
  1442. (ObjectContent->MemoryContent.ContentBytes != NULL)
  1443. ) {
  1444. // convert Printer content
  1445. result->MemoryContent.ContentBytes = IsmGetMemory (sizeof (PRINTER_DATAW));
  1446. if (result->MemoryContent.ContentBytes) {
  1447. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->Default =
  1448. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->Default;
  1449. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmFields =
  1450. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmFields;
  1451. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmOrientation =
  1452. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmOrientation;
  1453. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPaperSize =
  1454. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPaperSize;
  1455. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPaperLength =
  1456. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPaperLength;
  1457. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPaperWidth =
  1458. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPaperWidth;
  1459. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPosition.x =
  1460. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPosition.x;
  1461. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPosition.y =
  1462. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPosition.y;
  1463. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmScale =
  1464. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmScale;
  1465. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmCopies =
  1466. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmCopies;
  1467. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmDefaultSource =
  1468. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmDefaultSource;
  1469. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPrintQuality =
  1470. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPrintQuality;
  1471. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmColor =
  1472. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmColor;
  1473. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmDuplex =
  1474. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmDuplex;
  1475. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmYResolution =
  1476. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmYResolution;
  1477. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmTTOption =
  1478. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmTTOption;
  1479. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmCollate =
  1480. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmCollate;
  1481. DirectUnicodeToDbcsN (
  1482. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmFormName,
  1483. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmFormName,
  1484. CCHFORMNAME
  1485. );
  1486. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmLogPixels =
  1487. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmLogPixels;
  1488. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmBitsPerPel =
  1489. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmBitsPerPel;
  1490. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPelsWidth =
  1491. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPelsWidth;
  1492. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPelsHeight =
  1493. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPelsHeight;
  1494. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmDisplayFlags =
  1495. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmDisplayFlags;
  1496. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmNup =
  1497. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmNup;
  1498. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmDisplayFrequency =
  1499. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmDisplayFrequency;
  1500. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmICMMethod =
  1501. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmICMMethod;
  1502. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmICMIntent =
  1503. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmICMIntent;
  1504. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmMediaType =
  1505. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmMediaType;
  1506. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmDitherType =
  1507. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmDitherType;
  1508. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPanningWidth =
  1509. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPanningWidth;
  1510. ((PPRINTER_DATAA)result->MemoryContent.ContentBytes)->dmPanningHeight =
  1511. ((PPRINTER_DATAW)ObjectContent->MemoryContent.ContentBytes)->dmPanningHeight;
  1512. result->MemoryContent.ContentSize = sizeof (PRINTER_DATAA);
  1513. }
  1514. }
  1515. }
  1516. return result;
  1517. }
  1518. BOOL
  1519. FreeConvertedPrinterContent (
  1520. IN PMIG_CONTENT ObjectContent
  1521. )
  1522. {
  1523. if (!ObjectContent) {
  1524. return TRUE;
  1525. }
  1526. if (ObjectContent->MemoryContent.ContentBytes) {
  1527. IsmReleaseMemory (ObjectContent->MemoryContent.ContentBytes);
  1528. }
  1529. IsmReleaseMemory (ObjectContent);
  1530. return TRUE;
  1531. }