Ian Pilcher pilcher@concentric.net writes:
Sounds like importing winspool.drv in wineps creates a circular load dependency (user32->gdi32->wineps->winspool->comctl32->user32). We could probably be a bit more clever about loading wineps only when really necessary; OTOH there is no reason for winspool.drv to require comctl32. Something like this should fix it (completely untested, so it's probably broken):
Index: dlls/winspool/info.c =================================================================== RCS file: /opt/cvs-commit/wine/dlls/winspool/info.c,v retrieving revision 1.33 diff -u -r1.33 info.c --- dlls/winspool/info.c 2001/02/21 04:00:40 1.33 +++ dlls/winspool/info.c 2001/02/26 23:01:57 @@ -20,23 +20,12 @@ #include "wine/unicode.h" #include "debugtools.h" #include "heap.h" -#include "commctrl.h" #include "winnls.h"
DEFAULT_DEBUG_CHANNEL(winspool);
-typedef struct _OPENEDPRINTER -{ - LPWSTR lpsPrinterName; - HANDLE hPrinter; -} OPENEDPRINTER, *LPOPENEDPRINTER; - -/* The OpenedPrinter Table dynamic array */ -static HDPA pOpenedPrinterDPA = NULL; - -extern HDPA WINAPI (*WINSPOOL_DPA_CreateEx) (INT, HANDLE); -extern LPVOID WINAPI (*WINSPOOL_DPA_GetPtr) (const HDPA, INT); -extern INT WINAPI (*WINSPOOL_DPA_InsertPtr) (const HDPA, INT, LPVOID); +static LPWSTR *printer_array; +static int nb_printers;
static DWORD WINAPI (*GDI_CallDeviceCapabilities16)( LPCSTR lpszDevice, LPCSTR lpszPort, WORD fwCapability, LPSTR lpszOutput, @@ -84,73 +73,42 @@ * WINSPOOL_GetOpenedPrinterEntry * Get the first place empty in the opened printer table */ -static LPOPENEDPRINTER WINSPOOL_GetOpenedPrinterEntry() +static HANDLE WINSPOOL_GetOpenedPrinterEntry( LPCWSTR name ) { int i; - LPOPENEDPRINTER pOpenedPrinter;
- /* - * Create the opened printers' handle dynamic array. - */ - if (!pOpenedPrinterDPA) - { - pOpenedPrinterDPA = WINSPOOL_DPA_CreateEx(10, GetProcessHeap()); - for (i = 0; i < 10; i++) - { - pOpenedPrinter = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - sizeof(OPENEDPRINTER)); - pOpenedPrinter->hPrinter = -1; - WINSPOOL_DPA_InsertPtr(pOpenedPrinterDPA, i, pOpenedPrinter); - } - } + for (i = 0; i < nb_printers; i++) if (!printer_array[i]) break;
- /* - * Search for a handle not yet allocated. - */ - for (i = 0; i < pOpenedPrinterDPA->nItemCount; i++) + if (i >= nb_printers) { - pOpenedPrinter = WINSPOOL_DPA_GetPtr(pOpenedPrinterDPA, i); - - if (pOpenedPrinter->hPrinter == -1) - { - pOpenedPrinter->hPrinter = i + 1; - return pOpenedPrinter; - } + LPWSTR *new_array = HeapReAlloc( GetProcessHeap(), 0, printer_array, + (nb_printers + 16) * sizeof(*new_array) ); + if (!new_array) return 0; + printer_array = new_array; + nb_printers += 16; }
- /* - * Didn't find one, insert new element in the array. - */ - if (i == pOpenedPrinterDPA->nItemCount) + if ((printer_array[i] = HeapAlloc( GetProcessHeap(), 0, (strlenW(name)+1)*sizeof(WCHAR) ))) { - pOpenedPrinter = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - sizeof(OPENEDPRINTER)); - pOpenedPrinter->hPrinter = i + 1; - WINSPOOL_DPA_InsertPtr(pOpenedPrinterDPA, i, pOpenedPrinter); - return pOpenedPrinter; + strcpyW( printer_array[i], name ); + return (HANDLE)(i + 1); } - - return NULL; + return 0; }
/****************************************************************** * WINSPOOL_GetOpenedPrinter * Get the pointer to the opened printer referred by the handle */ -static LPOPENEDPRINTER WINSPOOL_GetOpenedPrinter(int printerHandle) +static LPCWSTR WINSPOOL_GetOpenedPrinter(HANDLE printerHandle) { - LPOPENEDPRINTER pOpenedPrinter; - - if(!pOpenedPrinterDPA) return NULL; - if((printerHandle <=0) || - (printerHandle > (pOpenedPrinterDPA->nItemCount - 1))) + int idx = (int)printerHandle; + if ((idx <= 0) || (idx > nb_printers)) + { + SetLastError(ERROR_INVALID_HANDLE); return NULL; - - pOpenedPrinter = WINSPOOL_DPA_GetPtr(pOpenedPrinterDPA, printerHandle-1); - - return pOpenedPrinter; + } + return printer_array[idx - 1]; }
/****************************************************************** @@ -159,21 +117,20 @@ */ static DWORD WINSPOOL_GetOpenedPrinterRegKey(HANDLE hPrinter, HKEY *phkey) { - LPOPENEDPRINTER lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); + LPCWSTR name = WINSPOOL_GetOpenedPrinter(hPrinter); DWORD ret; HKEY hkeyPrinters;
- if(!lpOpenedPrinter) - return ERROR_INVALID_HANDLE; + if(!name) return ERROR_INVALID_HANDLE;
if((ret = RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters)) != ERROR_SUCCESS) return ret;
- if(RegOpenKeyW(hkeyPrinters, lpOpenedPrinter->lpsPrinterName, phkey) - != ERROR_SUCCESS) { + if(RegOpenKeyW(hkeyPrinters, name, phkey) != ERROR_SUCCESS) + { ERR("Can't find opened printer %s in registry\n", - debugstr_w(lpOpenedPrinter->lpsPrinterName)); + debugstr_w(name)); RegCloseKey(hkeyPrinters); return ERROR_INVALID_PRINTER_NAME; /* ? */ } @@ -408,7 +365,6 @@ LPSTR pDeviceName, LPDEVMODEA pDevModeOutput, LPDEVMODEA pDevModeInput,DWORD fMode ) { - LPOPENEDPRINTER lpOpenedPrinter; LPSTR lpName = pDeviceName; LONG ret;
@@ -417,13 +373,8 @@ );
if(!pDeviceName) { - LPWSTR lpNameW; - lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); - if(!lpOpenedPrinter) { - SetLastError(ERROR_INVALID_HANDLE); - return -1; - } - lpNameW = lpOpenedPrinter->lpsPrinterName; + LPCWSTR lpNameW = WINSPOOL_GetOpenedPrinter(hPrinter); + if(!lpNameW) return -1; lpName = HEAP_strdupWtoA(GetProcessHeap(),0,lpNameW); }
@@ -512,7 +463,6 @@ BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter, LPPRINTER_DEFAULTSW pDefault) { - LPOPENEDPRINTER lpOpenedPrinter; HKEY hkeyPrinters, hkeyPrinter;
if (!lpPrinterName) { @@ -545,21 +495,8 @@ if(!phPrinter) /* This seems to be what win95 does anyway */ return TRUE;
- /* Get a place in the opened printer buffer*/ - lpOpenedPrinter = WINSPOOL_GetOpenedPrinterEntry(); - if(!lpOpenedPrinter) { - ERR("Can't allocate printer slot\n"); - SetLastError(ERROR_OUTOFMEMORY); - return FALSE; - } - - /* Get the name of the printer */ - lpOpenedPrinter->lpsPrinterName = HeapAlloc( GetProcessHeap(), 0, - (strlenW(lpPrinterName)+1)*sizeof(WCHAR) ); - strcpyW( lpOpenedPrinter->lpsPrinterName, lpPrinterName ); - /* Get the unique handle of the printer*/ - *phPrinter = lpOpenedPrinter->hPrinter; + *phPrinter = WINSPOOL_GetOpenedPrinterEntry( lpPrinterName );
if (pDefault != NULL) FIXME("Not handling pDefault\n"); @@ -915,23 +852,14 @@ */ BOOL WINAPI ClosePrinter(HANDLE hPrinter) { - LPOPENEDPRINTER lpOpenedPrinter; + int i = (int)hPrinter;
TRACE("Handle %d\n", hPrinter); - - if (!pOpenedPrinterDPA) - return FALSE;
- if ((hPrinter != -1) && (hPrinter < (pOpenedPrinterDPA->nItemCount - 1))) - { - lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); - HeapFree(GetProcessHeap(), 0, lpOpenedPrinter->lpsPrinterName); - lpOpenedPrinter->lpsPrinterName = NULL; - lpOpenedPrinter->hPrinter = -1; - - return TRUE; - } - return FALSE; + if ((i <= 0) || (i > nb_printers)) return FALSE; + HeapFree( GetProcessHeap(), 0, printer_array[i - 1] ); + printer_array[i - 1] = NULL; + return TRUE; }
/***************************************************************************** @@ -957,15 +885,10 @@ */ BOOL WINAPI DeletePrinter(HANDLE hPrinter) { - LPWSTR lpNameW; + LPCWSTR lpNameW = WINSPOOL_GetOpenedPrinter(hPrinter); HKEY hkeyPrinters;
- LPOPENEDPRINTER lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); - if(!lpOpenedPrinter) { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } - lpNameW = lpOpenedPrinter->lpsPrinterName; + if(!lpNameW) return FALSE; if(RegOpenKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) != ERROR_SUCCESS) { ERR("Can't open Printers key\n"); @@ -1410,7 +1333,7 @@ static BOOL WINSPOOL_GetPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded, BOOL unicode) { - OPENEDPRINTER *lpOpenedPrinter; + LPCWSTR name; DWORD size, needed = 0; LPBYTE ptr = NULL; HKEY hkeyPrinter, hkeyPrinters; @@ -1418,20 +1341,16 @@
TRACE("(%d,%ld,%p,%ld,%p)\n",hPrinter,Level,pPrinter,cbBuf, pcbNeeded);
- lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); - if(!lpOpenedPrinter) { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + if (!(name = WINSPOOL_GetOpenedPrinter(hPrinter))) return FALSE; + if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) != ERROR_SUCCESS) { ERR("Can't create Printers key\n"); return FALSE; } - if(RegOpenKeyW(hkeyPrinters, lpOpenedPrinter->lpsPrinterName, &hkeyPrinter) - != ERROR_SUCCESS) { - ERR("Can't find opened printer %s in registry\n", - debugstr_w(lpOpenedPrinter->lpsPrinterName)); + if(RegOpenKeyW(hkeyPrinters, name, &hkeyPrinter) != ERROR_SUCCESS) + { + ERR("Can't find opened printer %s in registry\n", debugstr_w(name)); RegCloseKey(hkeyPrinters); SetLastError(ERROR_INVALID_PRINTER_NAME); /* ? */ return FALSE; @@ -1933,7 +1852,7 @@ DWORD cbBuf, LPDWORD pcbNeeded, BOOL unicode) { - OPENEDPRINTER *lpOpenedPrinter; + LPCWSTR name; WCHAR DriverName[100]; DWORD ret, type, size, needed = 0; LPBYTE ptr = NULL; @@ -1944,11 +1863,8 @@
ZeroMemory(pDriverInfo, cbBuf);
- lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); - if(!lpOpenedPrinter) { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + if (!(name = WINSPOOL_GetOpenedPrinter(hPrinter))) return FALSE; + if(Level < 1 || Level > 3) { SetLastError(ERROR_INVALID_LEVEL); return FALSE; @@ -1958,10 +1874,9 @@ ERR("Can't create Printers key\n"); return FALSE; } - if(RegOpenKeyW(hkeyPrinters, lpOpenedPrinter->lpsPrinterName, &hkeyPrinter) + if(RegOpenKeyW(hkeyPrinters, name, &hkeyPrinter) != ERROR_SUCCESS) { - ERR("Can't find opened printer %s in registry\n", - debugstr_w(lpOpenedPrinter->lpsPrinterName)); + ERR("Can't find opened printer %s in registry\n", debugstr_w(name)); RegCloseKey(hkeyPrinters); SetLastError(ERROR_INVALID_PRINTER_NAME); /* ? */ return FALSE; @@ -1972,8 +1887,7 @@ RegCloseKey(hkeyPrinter); RegCloseKey(hkeyPrinters); if(ret != ERROR_SUCCESS) { - ERR("Can't get DriverName for printer %s\n", - debugstr_w(lpOpenedPrinter->lpsPrinterName)); + ERR("Can't get DriverName for printer %s\n", debugstr_w(name)); return FALSE; }
Index: dlls/winspool/wspool.c =================================================================== RCS file: /opt/cvs-commit/wine/dlls/winspool/wspool.c,v retrieving revision 1.3 diff -u -r1.3 wspool.c --- dlls/winspool/wspool.c 2001/02/12 03:51:05 1.3 +++ dlls/winspool/wspool.c 2001/02/26 23:01:57 @@ -5,15 +5,10 @@ * Copyright 1999 Thuy Nguyen */
-#include "commctrl.h" #include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(winspool);
-HINSTANCE hcomctl32 = 0; -HDPA WINAPI (*WINSPOOL_DPA_CreateEx)(INT, HANDLE); -LPVOID WINAPI (*WINSPOOL_DPA_GetPtr)(const HDPA, INT); -INT WINAPI (*WINSPOOL_DPA_InsertPtr)(const HDPA, INT, LPVOID);
/****************************************************************************** * WINSPOOL_EntryPoint @@ -28,16 +23,9 @@ switch (reason) { case DLL_PROCESS_ATTACH: - - hcomctl32 = LoadLibraryA("COMCTL32.DLL"); - - WINSPOOL_DPA_CreateEx = (void*)GetProcAddress(hcomctl32, (LPCSTR)340L); - WINSPOOL_DPA_GetPtr = (void*)GetProcAddress(hcomctl32, (LPCSTR)332L); - WINSPOOL_DPA_InsertPtr = (void*)GetProcAddress(hcomctl32, (LPCSTR)334L); break;
case DLL_PROCESS_DETACH: - FreeLibrary(hcomctl32); break; }
Alexandre Julliard wrote:
It appears to work, based on my admittedly incomplete test -- starting Lotus Notes and printing a document. No more invalid heap error messages.
Any idea when Windows loads printer drivers?
On Mon, Feb 26, 2001 at 11:07:27PM +0600, Ian Pilcher wrote:
Any idea when Windows loads printer drivers?
Usually on CreateDC/IC or OpenPrinter.
Huw.
Huw D M Davies wrote:
Any idea when Windows loads printer drivers?
Usually on CreateDC/IC or OpenPrinter.
Well, since I can't whip out 400-line patches the way Alexandre can, I'll see if I can move the LoadLibrary call.