Commit e1635e9a authored by Alexandre Julliard's avatar Alexandre Julliard

Removed dependency on comctl32.

parent 880cd395
...@@ -20,23 +20,12 @@ ...@@ -20,23 +20,12 @@
#include "wine/unicode.h" #include "wine/unicode.h"
#include "debugtools.h" #include "debugtools.h"
#include "heap.h" #include "heap.h"
#include "commctrl.h"
#include "winnls.h" #include "winnls.h"
DEFAULT_DEBUG_CHANNEL(winspool); DEFAULT_DEBUG_CHANNEL(winspool);
typedef struct _OPENEDPRINTER static LPWSTR *printer_array;
{ static int nb_printers;
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 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,
...@@ -84,73 +73,42 @@ static WCHAR WinPrintW[] = {'W','i','n','P','r','i','n','t',0}; ...@@ -84,73 +73,42 @@ static WCHAR WinPrintW[] = {'W','i','n','P','r','i','n','t',0};
* WINSPOOL_GetOpenedPrinterEntry * WINSPOOL_GetOpenedPrinterEntry
* Get the first place empty in the opened printer table * Get the first place empty in the opened printer table
*/ */
static LPOPENEDPRINTER WINSPOOL_GetOpenedPrinterEntry() static HANDLE WINSPOOL_GetOpenedPrinterEntry( LPCWSTR name )
{ {
int i; int i;
LPOPENEDPRINTER pOpenedPrinter;
/* for (i = 0; i < nb_printers; i++) if (!printer_array[i]) break;
* 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);
}
}
/* if (i >= nb_printers)
* Search for a handle not yet allocated.
*/
for (i = 0; i < pOpenedPrinterDPA->nItemCount; i++)
{ {
pOpenedPrinter = WINSPOOL_DPA_GetPtr(pOpenedPrinterDPA, i); LPWSTR *new_array = HeapReAlloc( GetProcessHeap(), 0, printer_array,
(nb_printers + 16) * sizeof(*new_array) );
if (pOpenedPrinter->hPrinter == -1) if (!new_array) return 0;
{ printer_array = new_array;
pOpenedPrinter->hPrinter = i + 1; nb_printers += 16;
return pOpenedPrinter;
}
} }
/* if ((printer_array[i] = HeapAlloc( GetProcessHeap(), 0, (strlenW(name)+1)*sizeof(WCHAR) )))
* Didn't find one, insert new element in the array.
*/
if (i == pOpenedPrinterDPA->nItemCount)
{ {
pOpenedPrinter = HeapAlloc(GetProcessHeap(), strcpyW( printer_array[i], name );
HEAP_ZERO_MEMORY, return (HANDLE)(i + 1);
sizeof(OPENEDPRINTER));
pOpenedPrinter->hPrinter = i + 1;
WINSPOOL_DPA_InsertPtr(pOpenedPrinterDPA, i, pOpenedPrinter);
return pOpenedPrinter;
} }
return 0;
return NULL;
} }
/****************************************************************** /******************************************************************
* WINSPOOL_GetOpenedPrinter * WINSPOOL_GetOpenedPrinter
* Get the pointer to the opened printer referred by the handle * 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; int idx = (int)printerHandle;
if ((idx <= 0) || (idx > nb_printers))
if(!pOpenedPrinterDPA) return NULL; {
if((printerHandle <=0) || SetLastError(ERROR_INVALID_HANDLE);
(printerHandle > (pOpenedPrinterDPA->nItemCount - 1)))
return NULL; return NULL;
}
pOpenedPrinter = WINSPOOL_DPA_GetPtr(pOpenedPrinterDPA, printerHandle-1); return printer_array[idx - 1];
return pOpenedPrinter;
} }
/****************************************************************** /******************************************************************
...@@ -159,21 +117,20 @@ static LPOPENEDPRINTER WINSPOOL_GetOpenedPrinter(int printerHandle) ...@@ -159,21 +117,20 @@ static LPOPENEDPRINTER WINSPOOL_GetOpenedPrinter(int printerHandle)
*/ */
static DWORD WINSPOOL_GetOpenedPrinterRegKey(HANDLE hPrinter, HKEY *phkey) static DWORD WINSPOOL_GetOpenedPrinterRegKey(HANDLE hPrinter, HKEY *phkey)
{ {
LPOPENEDPRINTER lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); LPCWSTR name = WINSPOOL_GetOpenedPrinter(hPrinter);
DWORD ret; DWORD ret;
HKEY hkeyPrinters; HKEY hkeyPrinters;
if(!lpOpenedPrinter) if(!name) return ERROR_INVALID_HANDLE;
return ERROR_INVALID_HANDLE;
if((ret = RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters)) != if((ret = RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters)) !=
ERROR_SUCCESS) ERROR_SUCCESS)
return ret; return ret;
if(RegOpenKeyW(hkeyPrinters, lpOpenedPrinter->lpsPrinterName, phkey) if(RegOpenKeyW(hkeyPrinters, name, phkey) != ERROR_SUCCESS)
!= ERROR_SUCCESS) { {
ERR("Can't find opened printer %s in registry\n", ERR("Can't find opened printer %s in registry\n",
debugstr_w(lpOpenedPrinter->lpsPrinterName)); debugstr_w(name));
RegCloseKey(hkeyPrinters); RegCloseKey(hkeyPrinters);
return ERROR_INVALID_PRINTER_NAME; /* ? */ return ERROR_INVALID_PRINTER_NAME; /* ? */
} }
...@@ -408,7 +365,6 @@ LONG WINAPI DocumentPropertiesA(HWND hWnd,HANDLE hPrinter, ...@@ -408,7 +365,6 @@ LONG WINAPI DocumentPropertiesA(HWND hWnd,HANDLE hPrinter,
LPSTR pDeviceName, LPDEVMODEA pDevModeOutput, LPSTR pDeviceName, LPDEVMODEA pDevModeOutput,
LPDEVMODEA pDevModeInput,DWORD fMode ) LPDEVMODEA pDevModeInput,DWORD fMode )
{ {
LPOPENEDPRINTER lpOpenedPrinter;
LPSTR lpName = pDeviceName; LPSTR lpName = pDeviceName;
LONG ret; LONG ret;
...@@ -417,13 +373,8 @@ LONG WINAPI DocumentPropertiesA(HWND hWnd,HANDLE hPrinter, ...@@ -417,13 +373,8 @@ LONG WINAPI DocumentPropertiesA(HWND hWnd,HANDLE hPrinter,
); );
if(!pDeviceName) { if(!pDeviceName) {
LPWSTR lpNameW; LPCWSTR lpNameW = WINSPOOL_GetOpenedPrinter(hPrinter);
lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); if(!lpNameW) return -1;
if(!lpOpenedPrinter) {
SetLastError(ERROR_INVALID_HANDLE);
return -1;
}
lpNameW = lpOpenedPrinter->lpsPrinterName;
lpName = HEAP_strdupWtoA(GetProcessHeap(),0,lpNameW); lpName = HEAP_strdupWtoA(GetProcessHeap(),0,lpNameW);
} }
...@@ -512,7 +463,6 @@ BOOL WINAPI OpenPrinterA(LPSTR lpPrinterName,HANDLE *phPrinter, ...@@ -512,7 +463,6 @@ BOOL WINAPI OpenPrinterA(LPSTR lpPrinterName,HANDLE *phPrinter,
BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter, BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter,
LPPRINTER_DEFAULTSW pDefault) LPPRINTER_DEFAULTSW pDefault)
{ {
LPOPENEDPRINTER lpOpenedPrinter;
HKEY hkeyPrinters, hkeyPrinter; HKEY hkeyPrinters, hkeyPrinter;
if (!lpPrinterName) { if (!lpPrinterName) {
...@@ -545,21 +495,8 @@ BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter, ...@@ -545,21 +495,8 @@ BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter,
if(!phPrinter) /* This seems to be what win95 does anyway */ if(!phPrinter) /* This seems to be what win95 does anyway */
return TRUE; 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*/ /* Get the unique handle of the printer*/
*phPrinter = lpOpenedPrinter->hPrinter; *phPrinter = WINSPOOL_GetOpenedPrinterEntry( lpPrinterName );
if (pDefault != NULL) if (pDefault != NULL)
FIXME("Not handling pDefault\n"); FIXME("Not handling pDefault\n");
...@@ -915,23 +852,14 @@ HANDLE WINAPI AddPrinterA(LPSTR pName, DWORD Level, LPBYTE pPrinter) ...@@ -915,23 +852,14 @@ HANDLE WINAPI AddPrinterA(LPSTR pName, DWORD Level, LPBYTE pPrinter)
*/ */
BOOL WINAPI ClosePrinter(HANDLE hPrinter) BOOL WINAPI ClosePrinter(HANDLE hPrinter)
{ {
LPOPENEDPRINTER lpOpenedPrinter; int i = (int)hPrinter;
TRACE("Handle %d\n", hPrinter); TRACE("Handle %d\n", hPrinter);
if (!pOpenedPrinterDPA) if ((i <= 0) || (i > nb_printers)) return FALSE;
return FALSE; HeapFree( GetProcessHeap(), 0, printer_array[i - 1] );
printer_array[i - 1] = NULL;
if ((hPrinter != -1) && (hPrinter < (pOpenedPrinterDPA->nItemCount - 1))) return TRUE;
{
lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter);
HeapFree(GetProcessHeap(), 0, lpOpenedPrinter->lpsPrinterName);
lpOpenedPrinter->lpsPrinterName = NULL;
lpOpenedPrinter->hPrinter = -1;
return TRUE;
}
return FALSE;
} }
/***************************************************************************** /*****************************************************************************
...@@ -957,15 +885,10 @@ BOOL WINAPI DeleteFormW(HANDLE hPrinter, LPWSTR pFormName) ...@@ -957,15 +885,10 @@ BOOL WINAPI DeleteFormW(HANDLE hPrinter, LPWSTR pFormName)
*/ */
BOOL WINAPI DeletePrinter(HANDLE hPrinter) BOOL WINAPI DeletePrinter(HANDLE hPrinter)
{ {
LPWSTR lpNameW; LPCWSTR lpNameW = WINSPOOL_GetOpenedPrinter(hPrinter);
HKEY hkeyPrinters; HKEY hkeyPrinters;
LPOPENEDPRINTER lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); if(!lpNameW) return FALSE;
if(!lpOpenedPrinter) {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
lpNameW = lpOpenedPrinter->lpsPrinterName;
if(RegOpenKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) != if(RegOpenKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) !=
ERROR_SUCCESS) { ERROR_SUCCESS) {
ERR("Can't open Printers key\n"); ERR("Can't open Printers key\n");
...@@ -1410,7 +1333,7 @@ static BOOL WINSPOOL_GetPrinter_5(HKEY hkeyPrinter, PRINTER_INFO_5W *pi5, ...@@ -1410,7 +1333,7 @@ static BOOL WINSPOOL_GetPrinter_5(HKEY hkeyPrinter, PRINTER_INFO_5W *pi5,
static BOOL WINSPOOL_GetPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, static BOOL WINSPOOL_GetPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter,
DWORD cbBuf, LPDWORD pcbNeeded, BOOL unicode) DWORD cbBuf, LPDWORD pcbNeeded, BOOL unicode)
{ {
OPENEDPRINTER *lpOpenedPrinter; LPCWSTR name;
DWORD size, needed = 0; DWORD size, needed = 0;
LPBYTE ptr = NULL; LPBYTE ptr = NULL;
HKEY hkeyPrinter, hkeyPrinters; HKEY hkeyPrinter, hkeyPrinters;
...@@ -1418,20 +1341,16 @@ static BOOL WINSPOOL_GetPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, ...@@ -1418,20 +1341,16 @@ static BOOL WINSPOOL_GetPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter,
TRACE("(%d,%ld,%p,%ld,%p)\n",hPrinter,Level,pPrinter,cbBuf, pcbNeeded); TRACE("(%d,%ld,%p,%ld,%p)\n",hPrinter,Level,pPrinter,cbBuf, pcbNeeded);
lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); if (!(name = WINSPOOL_GetOpenedPrinter(hPrinter))) return FALSE;
if(!lpOpenedPrinter) {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) != if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) !=
ERROR_SUCCESS) { ERROR_SUCCESS) {
ERR("Can't create Printers key\n"); ERR("Can't create Printers key\n");
return FALSE; return FALSE;
} }
if(RegOpenKeyW(hkeyPrinters, lpOpenedPrinter->lpsPrinterName, &hkeyPrinter) if(RegOpenKeyW(hkeyPrinters, name, &hkeyPrinter) != ERROR_SUCCESS)
!= 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(lpOpenedPrinter->lpsPrinterName));
RegCloseKey(hkeyPrinters); RegCloseKey(hkeyPrinters);
SetLastError(ERROR_INVALID_PRINTER_NAME); /* ? */ SetLastError(ERROR_INVALID_PRINTER_NAME); /* ? */
return FALSE; return FALSE;
...@@ -1707,9 +1626,9 @@ static BOOL WINSPOOL_EnumPrinters(DWORD dwType, LPWSTR lpszName, ...@@ -1707,9 +1626,9 @@ static BOOL WINSPOOL_EnumPrinters(DWORD dwType, LPWSTR lpszName,
* lpbPrinters buffer. * lpbPrinters buffer.
* *
* If level set to 3 or 6+: * If level set to 3 or 6+:
* returns zero (faillure!) * returns zero (failure!)
* *
* Returns nonzero (TRUE) on succes, or zero on faillure, use GetLastError * Returns nonzero (TRUE) on success, or zero on failure, use GetLastError
* for information. * for information.
* *
* BUGS: * BUGS:
...@@ -1933,7 +1852,7 @@ static BOOL WINSPOOL_GetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, ...@@ -1933,7 +1852,7 @@ static BOOL WINSPOOL_GetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment,
DWORD cbBuf, LPDWORD pcbNeeded, DWORD cbBuf, LPDWORD pcbNeeded,
BOOL unicode) BOOL unicode)
{ {
OPENEDPRINTER *lpOpenedPrinter; LPCWSTR name;
WCHAR DriverName[100]; WCHAR DriverName[100];
DWORD ret, type, size, needed = 0; DWORD ret, type, size, needed = 0;
LPBYTE ptr = NULL; LPBYTE ptr = NULL;
...@@ -1944,11 +1863,8 @@ static BOOL WINSPOOL_GetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, ...@@ -1944,11 +1863,8 @@ static BOOL WINSPOOL_GetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment,
ZeroMemory(pDriverInfo, cbBuf); ZeroMemory(pDriverInfo, cbBuf);
lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); if (!(name = WINSPOOL_GetOpenedPrinter(hPrinter))) return FALSE;
if(!lpOpenedPrinter) {
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;
...@@ -1958,10 +1874,9 @@ static BOOL WINSPOOL_GetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, ...@@ -1958,10 +1874,9 @@ static BOOL WINSPOOL_GetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment,
ERR("Can't create Printers key\n"); ERR("Can't create Printers key\n");
return FALSE; return FALSE;
} }
if(RegOpenKeyW(hkeyPrinters, lpOpenedPrinter->lpsPrinterName, &hkeyPrinter) if(RegOpenKeyW(hkeyPrinters, name, &hkeyPrinter)
!= ERROR_SUCCESS) { != 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(lpOpenedPrinter->lpsPrinterName));
RegCloseKey(hkeyPrinters); RegCloseKey(hkeyPrinters);
SetLastError(ERROR_INVALID_PRINTER_NAME); /* ? */ SetLastError(ERROR_INVALID_PRINTER_NAME); /* ? */
return FALSE; return FALSE;
...@@ -1972,8 +1887,7 @@ static BOOL WINSPOOL_GetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, ...@@ -1972,8 +1887,7 @@ static BOOL WINSPOOL_GetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment,
RegCloseKey(hkeyPrinter); RegCloseKey(hkeyPrinter);
RegCloseKey(hkeyPrinters); RegCloseKey(hkeyPrinters);
if(ret != ERROR_SUCCESS) { if(ret != ERROR_SUCCESS) {
ERR("Can't get DriverName for printer %s\n", ERR("Can't get DriverName for printer %s\n", debugstr_w(name));
debugstr_w(lpOpenedPrinter->lpsPrinterName));
return FALSE; return FALSE;
} }
...@@ -2202,7 +2116,7 @@ BOOL WINAPI AddPrinterDriverW(LPWSTR printerName,DWORD level, ...@@ -2202,7 +2116,7 @@ BOOL WINAPI AddPrinterDriverW(LPWSTR printerName,DWORD level,
* Displays a dialog to set the properties of the printer. * Displays a dialog to set the properties of the printer.
* *
* RETURNS * RETURNS
* nonzero on succes or zero on faillure * nonzero on success or zero on failure
* *
* BUGS * BUGS
* implemented as stub only * implemented as stub only
...@@ -2247,11 +2161,11 @@ BOOL WINAPI EnumJobsW(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, ...@@ -2247,11 +2161,11 @@ BOOL WINAPI EnumJobsW(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs,
/***************************************************************************** /*****************************************************************************
* WINSPOOL_EnumPrinterDrivers [internal] * WINSPOOL_EnumPrinterDrivers [internal]
* *
* Delivers information about all installed printer drivers installed on * Delivers information about all printer drivers installed on the
* localhost or a given server * localhost or a given server
* *
* RETURNS * RETURNS
* nonzero on succes or zero on failure, if the buffer for the returned * nonzero on success or zero on failure. If the buffer for the returned
* information is too small the function will return an error * information is too small the function will return an error
* *
* BUGS * BUGS
......
...@@ -5,15 +5,10 @@ ...@@ -5,15 +5,10 @@
* Copyright 1999 Thuy Nguyen * Copyright 1999 Thuy Nguyen
*/ */
#include "commctrl.h"
#include "debugtools.h" #include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(winspool); 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 * WINSPOOL_EntryPoint
...@@ -28,16 +23,9 @@ BOOL WINAPI WINSPOOL_EntryPoint(HINSTANCE hInstance, ...@@ -28,16 +23,9 @@ BOOL WINAPI WINSPOOL_EntryPoint(HINSTANCE hInstance,
switch (reason) switch (reason)
{ {
case DLL_PROCESS_ATTACH: 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; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
FreeLibrary(hcomctl32);
break; break;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment