Implemented AddPrinterA, AddPrinterDriverA and GetPrinterDriverDirectory
Moved some 16bit GDI function declarations from winspool.h -> wingdi16.h
diff --git a/dlls/winspool/info.c b/dlls/winspool/info.c
index 6ff0162..183d877 100644
--- a/dlls/winspool/info.c
+++ b/dlls/winspool/info.c
@@ -14,6 +14,7 @@
#include "winerror.h"
#include "winreg.h"
#include "debugtools.h"
+#include "heap.h"
DEFAULT_DEBUG_CHANNEL(winspool)
@@ -44,7 +45,10 @@
{NULL, -1, NULL}
};
-static char Printers[] = "System\\CurrentControlSet\\Control\\Print\\Printers\\";
+static char Printers[] =
+ "System\\CurrentControlSet\\control\\Print\\Printers\\";
+static char Drivers[] =
+ "System\\CurrentControlSet\\control\\Print\\Environments\\Wine\\Drivers\\";
/******************************************************************
@@ -646,7 +650,7 @@
/* Enter critical section to prevent AddPrinters() et al. to
* modify whilst we're reading in the registry
- */
+ */
InitializeCriticalSection(&PRINT32_RegistryBlocker);
EnterCriticalSection(&PRINT32_RegistryBlocker);
@@ -894,8 +898,100 @@
*/
HANDLE WINAPI AddPrinterA(LPSTR pName, DWORD Level, LPBYTE pPrinter)
{
- FIXME("(%s,%ld,%p): stub\n", pName, Level, pPrinter);
- return 0;
+ PRINTER_INFO_2A *pi = (PRINTER_INFO_2A *) pPrinter;
+
+ HANDLE retval;
+ HKEY hkeyPrinter, hkeyPrinters, hkeyDriver, hkeyDrivers;
+
+ TRACE("(%s,%ld,%p)\n", pName, Level, pPrinter);
+
+ if(pName != NULL) {
+ FIXME("pName = `%s' - unsupported\n", pName);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ if(Level != 2) {
+ WARN("Level = %ld\n", Level);
+ SetLastError(ERROR_INVALID_LEVEL);
+ return 0;
+ }
+ if(!pPrinter) {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) !=
+ ERROR_SUCCESS) {
+ ERR("Can't create Printers key\n");
+ return 0;
+ }
+ if(RegOpenKeyA(hkeyPrinters, pi->pPrinterName, &hkeyPrinter) ==
+ ERROR_SUCCESS) {
+ SetLastError(ERROR_PRINTER_ALREADY_EXISTS);
+ RegCloseKey(hkeyPrinter);
+ RegCloseKey(hkeyPrinters);
+ return 0;
+ }
+ if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Drivers, &hkeyDrivers) !=
+ ERROR_SUCCESS) {
+ ERR("Can't create Drivers key\n");
+ RegCloseKey(hkeyPrinters);
+ return 0;
+ }
+ if(RegOpenKeyA(hkeyDrivers, pi->pDriverName, &hkeyDriver) !=
+ ERROR_SUCCESS) {
+ WARN("Can't find driver `%s'\n", pi->pDriverName);
+ RegCloseKey(hkeyPrinters);
+ RegCloseKey(hkeyDrivers);
+ SetLastError(ERROR_UNKNOWN_PRINTER_DRIVER);
+ return 0;
+ }
+ RegCloseKey(hkeyDriver);
+ RegCloseKey(hkeyDrivers);
+ if(strcasecmp(pi->pPrintProcessor, "WinPrint")) { /* FIXME */
+ WARN("Can't find processor `%s'\n", pi->pPrintProcessor);
+ SetLastError(ERROR_UNKNOWN_PRINTPROCESSOR);
+ RegCloseKey(hkeyPrinters);
+ return 0;
+ }
+ if(RegCreateKeyA(hkeyPrinters, pi->pPrinterName, &hkeyPrinter) !=
+ ERROR_SUCCESS) {
+ WARN("Can't create printer `%s'\n", pi->pPrinterName);
+ SetLastError(ERROR_INVALID_PRINTER_NAME);
+ RegCloseKey(hkeyPrinters);
+ return 0;
+ }
+ RegSetValueExA(hkeyPrinter, "Attributes", 0, REG_DWORD,
+ (LPSTR)&pi->Attributes, sizeof(DWORD));
+ RegSetValueExA(hkeyPrinter, "Default DevMode", 0, REG_BINARY,
+ (LPSTR)&pi->pDevMode,
+ pi->pDevMode ? pi->pDevMode->dmSize : 0);
+ RegSetValueExA(hkeyPrinter, "Description", 0, REG_SZ, pi->pComment, 0);
+ RegSetValueExA(hkeyPrinter, "Location", 0, REG_SZ, pi->pLocation, 0);
+ RegSetValueExA(hkeyPrinter, "Name", 0, REG_SZ, pi->pPrinterName, 0);
+ RegSetValueExA(hkeyPrinter, "Parameters", 0, REG_SZ, pi->pParameters, 0);
+ RegSetValueExA(hkeyPrinter, "Port", 0, REG_SZ, pi->pPortName, 0);
+ RegSetValueExA(hkeyPrinter, "Print Processor", 0, REG_SZ,
+ pi->pPrintProcessor, 0);
+ RegSetValueExA(hkeyPrinter, "Printer Driver", 0, REG_SZ, pi->pDriverName,
+ 0);
+ RegSetValueExA(hkeyPrinter, "Priority", 0, REG_DWORD,
+ (LPSTR)&pi->Priority, sizeof(DWORD));
+ RegSetValueExA(hkeyPrinter, "Separator File", 0, REG_SZ, pi->pSepFile, 0);
+ RegSetValueExA(hkeyPrinter, "Share Name", 0, REG_SZ, pi->pShareName, 0);
+ RegSetValueExA(hkeyPrinter, "Start Time", 0, REG_DWORD,
+ (LPSTR)&pi->StartTime, sizeof(DWORD));
+ RegSetValueExA(hkeyPrinter, "Status", 0, REG_DWORD,
+ (LPSTR)&pi->Status, sizeof(DWORD));
+ RegSetValueExA(hkeyPrinter, "Until Time", 0, REG_DWORD,
+ (LPSTR)&pi->UntilTime, sizeof(DWORD));
+
+ RegCloseKey(hkeyPrinter);
+ RegCloseKey(hkeyPrinters);
+ if(!OpenPrinterA(pi->pPrinterName, &retval, NULL)) {
+ ERR("OpenPrinter failing\n");
+ return 0;
+ }
+ return retval;
}
/*****************************************************************************
@@ -1104,11 +1200,27 @@
* GetPrinterDriver32A [WINSPOOL.190]
*/
BOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment,
- DWORD Level, LPBYTE pDriverInfo,
- DWORD cbBuf, LPDWORD pcbNeeded)
+ DWORD Level, LPBYTE pDriverInfo,
+ DWORD cbBuf, LPDWORD pcbNeeded)
{
+ OPENEDPRINTERA *lpOpenedPrinter;
+ LPSTR lpName;
+
FIXME("(%d,%s,%ld,%p,%ld,%p): stub\n",hPrinter,pEnvironment,
Level,pDriverInfo,cbBuf, pcbNeeded);
+
+ lpOpenedPrinter = WINSPOOL_GetOpenedPrinterA(hPrinter);
+ if(!lpOpenedPrinter) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+ lpName = lpOpenedPrinter->lpsPrinterName;
+ if(pEnvironment) {
+ FIXME("pEnvironment = `%s'\n", pEnvironment);
+ SetLastError(ERROR_INVALID_ENVIRONMENT);
+ return FALSE;
+ }
+
return FALSE;
}
@@ -1123,14 +1235,150 @@
Level,pDriverInfo,cbBuf, pcbNeeded);
return FALSE;
}
+
+/*****************************************************************************
+ * GetPrinterDriverDirectoryA [WINSPOOL.191]
+ */
+BOOL WINAPI GetPrinterDriverDirectoryA(LPSTR pName, LPSTR pEnvironment,
+ DWORD Level, LPBYTE pDriverDirectory,
+ DWORD cbBuf, LPDWORD pcbNeeded)
+{
+ DWORD needed;
+
+ TRACE("(%s, %s, %ld, %p, %ld, %p)\n", pName, pEnvironment, Level,
+ pDriverDirectory, cbBuf, pcbNeeded);
+ if(pName != NULL) {
+ FIXME("pName = `%s' - unsupported\n", pName);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ if(pEnvironment != NULL) {
+ FIXME("pEnvironment = `%s' - unsupported\n", pEnvironment);
+ SetLastError(ERROR_INVALID_ENVIRONMENT);
+ return FALSE;
+ }
+ if(Level != 1) /* win95 ignores this so we just carry on */
+ WARN("Level = %ld - assuming 1\n", Level);
+
+ /* FIXME should read from registry */
+ needed = GetSystemDirectoryA(pDriverDirectory, cbBuf);
+ needed++;
+ if(pcbNeeded)
+ *pcbNeeded = needed;
+ if(needed > cbBuf) {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*****************************************************************************
+ * GetPrinterDriverDirectoryW [WINSPOOL.192]
+ */
+BOOL WINAPI GetPrinterDriverDirectoryW(LPWSTR pName, LPWSTR pEnvironment,
+ DWORD Level, LPBYTE pDriverDirectory,
+ DWORD cbBuf, LPDWORD pcbNeeded)
+{
+ LPSTR pNameA = NULL, pEnvironmentA = NULL;
+ BOOL ret;
+
+ if(pName)
+ pNameA = HEAP_strdupWtoA( GetProcessHeap(), 0, pName );
+ if(pEnvironment)
+ pEnvironmentA = HEAP_strdupWtoA( GetProcessHeap(), 0, pEnvironment );
+ ret = GetPrinterDriverDirectoryA( pNameA, pEnvironmentA, Level,
+ pDriverDirectory, cbBuf, pcbNeeded );
+ if(pNameA)
+ HeapFree( GetProcessHeap(), 0, pNameA );
+ if(pEnvironmentA)
+ HeapFree( GetProcessHeap(), 0, pEnvironment );
+
+ return ret;
+}
+
/*****************************************************************************
* AddPrinterDriver32A [WINSPOOL.120]
*/
-BOOL WINAPI AddPrinterDriverA(LPSTR printerName,DWORD level,
- LPBYTE pDriverInfo)
+BOOL WINAPI AddPrinterDriverA(LPSTR pName, DWORD level, LPBYTE pDriverInfo)
{
- FIXME("(%s,%ld,%p): stub\n",printerName,level,pDriverInfo);
- return FALSE;
+ DRIVER_INFO_3A di3;
+ HKEY hkeyDrivers, hkeyName;
+
+ TRACE("(%s,%ld,%p)\n",pName,level,pDriverInfo);
+
+ if(level != 2 && level != 3) {
+ SetLastError(ERROR_INVALID_LEVEL);
+ return FALSE;
+ }
+ if(pName != NULL) {
+ FIXME("pName= `%s' - unsupported\n", pName);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ if(!pDriverInfo) {
+ WARN("pDriverInfo == NULL");
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if(level == 3)
+ di3 = *(DRIVER_INFO_3A *)pDriverInfo;
+ else {
+ memset(&di3, 0, sizeof(di3));
+ *(DRIVER_INFO_2A *)&di3 = *(DRIVER_INFO_2A *)pDriverInfo;
+ }
+
+ if(!di3.pName || !di3.pDriverPath || !di3.pConfigFile ||
+ !di3.pDataFile) {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ if(!di3.pDefaultDataType) di3.pDefaultDataType = "";
+ if(!di3.pDependentFiles) di3.pDependentFiles = "\0";
+ if(!di3.pHelpFile) di3.pHelpFile = "";
+ if(!di3.pMonitorName) di3.pMonitorName = "";
+
+ if(di3.pEnvironment) {
+ FIXME("pEnvironment = `%s'\n", di3.pEnvironment);
+ SetLastError(ERROR_INVALID_ENVIRONMENT);
+ return FALSE;
+ }
+ if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Drivers, &hkeyDrivers) !=
+ ERROR_SUCCESS) {
+ ERR("Can't create Drivers key\n");
+ return FALSE;
+ }
+
+ if(level == 2) { /* apparently can't overwrite with level2 */
+ if(RegOpenKeyA(hkeyDrivers, di3.pName, &hkeyName) == ERROR_SUCCESS) {
+ RegCloseKey(hkeyName);
+ RegCloseKey(hkeyDrivers);
+ WARN("Trying to create existing printer driver `%s'\n", di3.pName);
+ SetLastError(ERROR_PRINTER_DRIVER_ALREADY_INSTALLED);
+ return FALSE;
+ }
+ }
+ if(RegCreateKeyA(hkeyDrivers, di3.pName, &hkeyName) != ERROR_SUCCESS) {
+ RegCloseKey(hkeyDrivers);
+ ERR("Can't create Name key\n");
+ return FALSE;
+ }
+ RegSetValueExA(hkeyName, "Configuration File", 0, REG_SZ, di3.pConfigFile,
+ 0);
+ RegSetValueExA(hkeyName, "Data File", 0, REG_SZ, di3.pDataFile, 0);
+ RegSetValueExA(hkeyName, "Driver", 0, REG_SZ, di3.pDriverPath, 0);
+ RegSetValueExA(hkeyName, "Version", 0, REG_DWORD, (LPSTR)&di3.cVersion,
+ sizeof(DWORD));
+ RegSetValueExA(hkeyName, "Datatype", 0, REG_SZ, di3.pDefaultDataType, 0);
+ RegSetValueExA(hkeyName, "Dependent Files", 0, REG_MULTI_SZ,
+ di3.pDependentFiles, 0);
+ RegSetValueExA(hkeyName, "Help File", 0, REG_SZ, di3.pHelpFile, 0);
+ RegSetValueExA(hkeyName, "Monitor", 0, REG_SZ, di3.pMonitorName, 0);
+ RegCloseKey(hkeyName);
+ RegCloseKey(hkeyDrivers);
+
+ return TRUE;
}
/*****************************************************************************
* AddPrinterDriver32W [WINSPOOL.121]