Add one more level of indirection to the printer handle array to allow
more information than just the name to be stored. Wrap accesses to the printer handle array in a critsec.
This commit is contained in:
parent
ea632a581a
commit
df9c4341ec
|
@ -57,8 +57,21 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(winspool);
|
WINE_DEFAULT_DEBUG_CHANNEL(winspool);
|
||||||
|
|
||||||
static LPWSTR *printer_array;
|
static CRITICAL_SECTION printer_handles_cs;
|
||||||
static int nb_printers;
|
static CRITICAL_SECTION_DEBUG printer_handles_cs_debug =
|
||||||
|
{
|
||||||
|
0, 0, &printer_handles_cs,
|
||||||
|
{ &printer_handles_cs_debug.ProcessLocksList, &printer_handles_cs_debug.ProcessLocksList },
|
||||||
|
0, 0, { 0, (DWORD)(__FILE__ ": printer_handles_cs") }
|
||||||
|
};
|
||||||
|
static CRITICAL_SECTION printer_handles_cs = { &printer_handles_cs_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
LPWSTR name;
|
||||||
|
} opened_printer_t;
|
||||||
|
|
||||||
|
static opened_printer_t **printer_handles;
|
||||||
|
static int nb_printer_handles;
|
||||||
|
|
||||||
static DWORD (WINAPI *GDI_CallDeviceCapabilities16)( LPCSTR lpszDevice, LPCSTR lpszPort,
|
static DWORD (WINAPI *GDI_CallDeviceCapabilities16)( LPCSTR lpszDevice, LPCSTR lpszPort,
|
||||||
WORD fwCapability, LPSTR lpszOutput,
|
WORD fwCapability, LPSTR lpszOutput,
|
||||||
|
@ -546,51 +559,83 @@ void WINSPOOL_LoadSystemPrinters(void)
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* WINSPOOL_GetOpenedPrinterEntry
|
* get_opened_printer_entry
|
||||||
* Get the first place empty in the opened printer table
|
* Get the first place empty in the opened printer table
|
||||||
*/
|
*/
|
||||||
static HANDLE WINSPOOL_GetOpenedPrinterEntry( LPCWSTR name )
|
static HANDLE get_opened_printer_entry( LPCWSTR name )
|
||||||
{
|
{
|
||||||
int i;
|
UINT handle;
|
||||||
|
|
||||||
for (i = 0; i < nb_printers; i++) if (!printer_array[i]) break;
|
EnterCriticalSection(&printer_handles_cs);
|
||||||
|
|
||||||
if (i >= nb_printers)
|
for (handle = 0; handle < nb_printer_handles; handle++)
|
||||||
|
if (!printer_handles[handle])
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (handle >= nb_printer_handles)
|
||||||
{
|
{
|
||||||
LPWSTR *new_array;
|
opened_printer_t **new_array;
|
||||||
if (printer_array)
|
if (printer_handles)
|
||||||
new_array = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, printer_array,
|
new_array = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, printer_handles,
|
||||||
(nb_printers + 16) * sizeof(*new_array) );
|
(nb_printer_handles + 16) * sizeof(*new_array) );
|
||||||
else
|
else
|
||||||
new_array = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
new_array = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
(nb_printers + 16) * sizeof(*new_array) );
|
(nb_printer_handles + 16) * sizeof(*new_array) );
|
||||||
|
|
||||||
if (!new_array) return 0;
|
if (!new_array)
|
||||||
printer_array = new_array;
|
{
|
||||||
nb_printers += 16;
|
handle = 0;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
printer_handles = new_array;
|
||||||
|
nb_printer_handles += 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((printer_array[i] = HeapAlloc( GetProcessHeap(), 0, (strlenW(name)+1)*sizeof(WCHAR) )))
|
if (!(printer_handles[handle] = HeapAlloc(GetProcessHeap(), 0, sizeof(**printer_handles))))
|
||||||
{
|
{
|
||||||
strcpyW( printer_array[i], name );
|
handle = 0;
|
||||||
return (HANDLE)(i + 1);
|
goto end;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
printer_handles[handle]->name = HeapAlloc(GetProcessHeap(), 0, (strlenW(name) + 1) * sizeof(WCHAR));
|
||||||
|
strcpyW(printer_handles[handle]->name, name);
|
||||||
|
|
||||||
|
handle++;
|
||||||
|
end:
|
||||||
|
LeaveCriticalSection(&printer_handles_cs);
|
||||||
|
|
||||||
|
return (HANDLE)handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* WINSPOOL_GetOpenedPrinter
|
* get_opened_printer
|
||||||
* Get the pointer to the opened printer referred by the handle
|
* Get the pointer to the opened printer referred by the handle
|
||||||
*/
|
*/
|
||||||
static LPCWSTR WINSPOOL_GetOpenedPrinter(HANDLE printerHandle)
|
static opened_printer_t *get_opened_printer(HANDLE hprn)
|
||||||
{
|
{
|
||||||
int idx = (int)printerHandle;
|
int idx = (int)hprn;
|
||||||
if ((idx <= 0) || (idx > nb_printers))
|
opened_printer_t *ret = NULL;
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
EnterCriticalSection(&printer_handles_cs);
|
||||||
return NULL;
|
|
||||||
}
|
if ((idx <= 0) || (idx > nb_printer_handles))
|
||||||
return printer_array[idx - 1];
|
goto end;
|
||||||
|
|
||||||
|
ret = printer_handles[idx - 1];
|
||||||
|
end:
|
||||||
|
LeaveCriticalSection(&printer_handles_cs);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* get_opened_printer_name
|
||||||
|
* Get the pointer to the opened printer name referred by the handle
|
||||||
|
*/
|
||||||
|
static LPCWSTR get_opened_printer_name(HANDLE hprn)
|
||||||
|
{
|
||||||
|
opened_printer_t *printer = get_opened_printer(hprn);
|
||||||
|
if(!printer) return NULL;
|
||||||
|
return printer->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
|
@ -599,7 +644,7 @@ static LPCWSTR WINSPOOL_GetOpenedPrinter(HANDLE printerHandle)
|
||||||
*/
|
*/
|
||||||
static DWORD WINSPOOL_GetOpenedPrinterRegKey(HANDLE hPrinter, HKEY *phkey)
|
static DWORD WINSPOOL_GetOpenedPrinterRegKey(HANDLE hPrinter, HKEY *phkey)
|
||||||
{
|
{
|
||||||
LPCWSTR name = WINSPOOL_GetOpenedPrinter(hPrinter);
|
LPCWSTR name = get_opened_printer_name(hPrinter);
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
HKEY hkeyPrinters;
|
HKEY hkeyPrinters;
|
||||||
|
|
||||||
|
@ -612,8 +657,8 @@ static DWORD WINSPOOL_GetOpenedPrinterRegKey(HANDLE hPrinter, HKEY *phkey)
|
||||||
if(RegOpenKeyW(hkeyPrinters, name, phkey) != ERROR_SUCCESS)
|
if(RegOpenKeyW(hkeyPrinters, name, phkey) != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
ERR("Can't find opened printer %s in registry\n",
|
ERR("Can't find opened printer %s in registry\n",
|
||||||
debugstr_w(name));
|
debugstr_w(name));
|
||||||
RegCloseKey(hkeyPrinters);
|
RegCloseKey(hkeyPrinters);
|
||||||
return ERROR_INVALID_PRINTER_NAME; /* ? */
|
return ERROR_INVALID_PRINTER_NAME; /* ? */
|
||||||
}
|
}
|
||||||
RegCloseKey(hkeyPrinters);
|
RegCloseKey(hkeyPrinters);
|
||||||
|
@ -839,9 +884,10 @@ LONG WINAPI DocumentPropertiesA(HWND hWnd,HANDLE hPrinter,
|
||||||
);
|
);
|
||||||
|
|
||||||
if(!pDeviceName) {
|
if(!pDeviceName) {
|
||||||
LPCWSTR lpNameW = WINSPOOL_GetOpenedPrinter(hPrinter);
|
LPCWSTR lpNameW = get_opened_printer_name(hPrinter);
|
||||||
if(!lpNameW) {
|
if(!lpNameW) {
|
||||||
ERR("no name from hPrinter?\n");
|
ERR("no name from hPrinter?\n");
|
||||||
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
lpName = HEAP_strdupWtoA(GetProcessHeap(),0,lpNameW);
|
lpName = HEAP_strdupWtoA(GetProcessHeap(),0,lpNameW);
|
||||||
|
@ -974,7 +1020,7 @@ BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* Get the unique handle of the printer*/
|
/* Get the unique handle of the printer*/
|
||||||
*phPrinter = WINSPOOL_GetOpenedPrinterEntry( lpPrinterName );
|
*phPrinter = get_opened_printer_entry( lpPrinterName );
|
||||||
|
|
||||||
if (pDefault != NULL)
|
if (pDefault != NULL)
|
||||||
FIXME("Not handling pDefault\n");
|
FIXME("Not handling pDefault\n");
|
||||||
|
@ -1433,13 +1479,27 @@ HANDLE WINAPI AddPrinterA(LPSTR pName, DWORD Level, LPBYTE pPrinter)
|
||||||
BOOL WINAPI ClosePrinter(HANDLE hPrinter)
|
BOOL WINAPI ClosePrinter(HANDLE hPrinter)
|
||||||
{
|
{
|
||||||
int i = (int)hPrinter;
|
int i = (int)hPrinter;
|
||||||
|
opened_printer_t *printer = NULL;
|
||||||
|
|
||||||
TRACE("Handle %p\n", hPrinter);
|
TRACE("Handle %p\n", hPrinter);
|
||||||
|
|
||||||
if ((i <= 0) || (i > nb_printers)) return FALSE;
|
EnterCriticalSection(&printer_handles_cs);
|
||||||
HeapFree( GetProcessHeap(), 0, printer_array[i - 1] );
|
|
||||||
printer_array[i - 1] = NULL;
|
if ((i > 0) && (i <= nb_printer_handles))
|
||||||
return TRUE;
|
{
|
||||||
|
printer = printer_handles[i - 1];
|
||||||
|
printer_handles[i - 1] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&printer_handles_cs);
|
||||||
|
|
||||||
|
if(printer)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, printer->name);
|
||||||
|
HeapFree(GetProcessHeap(), 0, printer);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
@ -1516,10 +1576,13 @@ static DWORD WINSPOOL_SHDeleteKeyW(HKEY hKey, LPCWSTR lpszSubKey)
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI DeletePrinter(HANDLE hPrinter)
|
BOOL WINAPI DeletePrinter(HANDLE hPrinter)
|
||||||
{
|
{
|
||||||
LPCWSTR lpNameW = WINSPOOL_GetOpenedPrinter(hPrinter);
|
LPCWSTR lpNameW = get_opened_printer_name(hPrinter);
|
||||||
HKEY hkeyPrinters, hkey;
|
HKEY hkeyPrinters, hkey;
|
||||||
|
|
||||||
if(!lpNameW) return FALSE;
|
if(!lpNameW) {
|
||||||
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
if(RegOpenKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) == ERROR_SUCCESS) {
|
if(RegOpenKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) == ERROR_SUCCESS) {
|
||||||
WINSPOOL_SHDeleteKeyW(hkeyPrinters, lpNameW);
|
WINSPOOL_SHDeleteKeyW(hkeyPrinters, lpNameW);
|
||||||
RegCloseKey(hkeyPrinters);
|
RegCloseKey(hkeyPrinters);
|
||||||
|
@ -2134,7 +2197,10 @@ static BOOL WINSPOOL_GetPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter,
|
||||||
|
|
||||||
TRACE("(%p,%ld,%p,%ld,%p)\n",hPrinter,Level,pPrinter,cbBuf, pcbNeeded);
|
TRACE("(%p,%ld,%p,%ld,%p)\n",hPrinter,Level,pPrinter,cbBuf, pcbNeeded);
|
||||||
|
|
||||||
if (!(name = WINSPOOL_GetOpenedPrinter(hPrinter))) return FALSE;
|
if (!(name = get_opened_printer_name(hPrinter))) {
|
||||||
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) !=
|
if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) !=
|
||||||
ERROR_SUCCESS) {
|
ERROR_SUCCESS) {
|
||||||
|
@ -2664,8 +2730,10 @@ static BOOL WINSPOOL_GetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment,
|
||||||
|
|
||||||
ZeroMemory(pDriverInfo, cbBuf);
|
ZeroMemory(pDriverInfo, cbBuf);
|
||||||
|
|
||||||
if (!(name = WINSPOOL_GetOpenedPrinter(hPrinter))) return FALSE;
|
if (!(name = get_opened_printer_name(hPrinter))) {
|
||||||
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
if(Level < 1 || Level > 3) {
|
if(Level < 1 || Level > 3) {
|
||||||
SetLastError(ERROR_INVALID_LEVEL);
|
SetLastError(ERROR_INVALID_LEVEL);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in New Issue