1 /* 2 * Implementation of the Spooler Setup API (Printing) 3 * 4 * Copyright 2007 Detlef Riekenberg 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <stdarg.h> 22 23 #define COBJMACROS 24 25 #include "windef.h" 26 #include "winbase.h" 27 #include "winerror.h" 28 #include "wingdi.h" 29 #include "winnls.h" 30 #include "winver.h" 31 #include "winspool.h" 32 33 #include "wine/debug.h" 34 35 WINE_DEFAULT_DEBUG_CHANNEL(ntprint); 36 37 typedef struct { 38 LPMONITOR_INFO_2W mi2; /* Buffer for installed Monitors */ 39 DWORD installed; /* Number of installed Monitors */ 40 } monitorinfo_t; 41 42 /***************************************************** 43 * DllMain 44 */ 45 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 46 { 47 TRACE("(%p, %d, %p)\n",hinstDLL, fdwReason, lpvReserved); 48 49 switch(fdwReason) 50 { 51 case DLL_WINE_PREATTACH: 52 return FALSE; /* prefer native version */ 53 54 case DLL_PROCESS_ATTACH: 55 DisableThreadLibraryCalls( hinstDLL ); 56 break; 57 } 58 return TRUE; 59 } 60 61 /***************************************************** 62 * PSetupCreateMonitorInfo [NTPRINT.@] 63 * 64 * 65 */ 66 67 HANDLE WINAPI PSetupCreateMonitorInfo(DWORD unknown1, WCHAR *server) 68 { 69 monitorinfo_t * mi=NULL; 70 DWORD needed; 71 DWORD res; 72 73 TRACE("(%d, %s)\n", unknown1, debugstr_w(server)); 74 75 mi = HeapAlloc(GetProcessHeap(), 0, sizeof(monitorinfo_t)); 76 if (!mi) { 77 /* FIXME: SetLastError() needed? */ 78 return NULL; 79 } 80 81 /* Get the needed size for all Monitors */ 82 res = EnumMonitorsW(server, 2, NULL, 0, &needed, &mi->installed); 83 if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { 84 mi->mi2 = HeapAlloc(GetProcessHeap(), 0, needed); 85 res = EnumMonitorsW(server, 2, (LPBYTE) mi->mi2, needed, &needed, &mi->installed); 86 } 87 88 if (!res) { 89 HeapFree(GetProcessHeap(), 0, mi); 90 return NULL; 91 } 92 93 TRACE("=> %p (%u monitors installed)\n", mi, mi->installed); 94 return mi; 95 } 96 97 /***************************************************** 98 * PSetupDestroyMonitorInfo [NTPRINT.@] 99 * 100 */ 101 102 VOID WINAPI PSetupDestroyMonitorInfo(HANDLE monitorinfo) 103 { 104 monitorinfo_t * mi = monitorinfo; 105 106 TRACE("(%p)\n", mi); 107 if (mi) { 108 if (mi->installed) HeapFree(GetProcessHeap(), 0, mi->mi2); 109 HeapFree(GetProcessHeap(), 0, mi); 110 } 111 } 112 113 /***************************************************** 114 * PSetupEnumMonitor [NTPRINT.@] 115 * 116 * Copy the selected Monitorname to a buffer 117 * 118 * PARAMS 119 * monitorinfo [I] HANDLE from PSetupCreateMonitorInfo 120 * index [I] Nr. of the Monitorname to copy 121 * buffer [I] Target, that receive the Monitorname 122 * psize [IO] PTR to a DWORD that hold the size of the buffer and receive 123 * the needed size, when the buffer is too small 124 * 125 * RETURNS 126 * Success: TRUE 127 * Failure: FALSE 128 * 129 * NOTES 130 * size is in Bytes on w2k and WCHAR on XP 131 * 132 */ 133 134 BOOL WINAPI PSetupEnumMonitor(HANDLE monitorinfo, DWORD index, LPWSTR buffer, LPDWORD psize) 135 { 136 monitorinfo_t * mi = monitorinfo; 137 LPWSTR nameW; 138 DWORD len; 139 140 TRACE("(%p, %u, %p, %p) => %d\n", mi, index, buffer, psize, psize ? *psize : 0); 141 142 if (index < mi->installed) { 143 nameW = mi->mi2[index].pName; 144 len = lstrlenW(nameW) + 1; 145 if (len <= *psize) { 146 memcpy(buffer, nameW, len * sizeof(WCHAR)); 147 TRACE("#%u: %s\n", index, debugstr_w(buffer)); 148 return TRUE; 149 } 150 *psize = len; 151 SetLastError(ERROR_INSUFFICIENT_BUFFER); 152 return FALSE; 153 } 154 SetLastError(ERROR_NO_MORE_ITEMS); 155 return FALSE; 156 } 157