winspool: AddJob and ScheduleJob
Huw D M Davies
h.davies1 at physics.ox.ac.uk
Wed Jul 6 08:11:34 CDT 2005
Huw Davies <huw at codeweavers.com>
Add an implementation of AddJob and a partial one of
ScheduleJob.
--
Huw Davies
huw at codeweavers.com
Index: dlls/winspool/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/winspool/Makefile.in,v
retrieving revision 1.29
diff -u -p -r1.29 Makefile.in
--- dlls/winspool/Makefile.in 31 May 2005 09:38:10 -0000 1.29
+++ dlls/winspool/Makefile.in 6 Jul 2005 13:05:59 -0000
@@ -6,6 +6,7 @@ VPATH = @srcdir@
MODULE = winspool.drv
IMPORTLIB = libwinspool.$(IMPLIBEXT)
IMPORTS = user32 gdi32 advapi32 kernel32 ntdll
+EXTRALIBS = $(LIBUNICODE)
C_SRCS = \
info.c \
Index: dlls/winspool/info.c
===================================================================
RCS file: /home/wine/wine/dlls/winspool/info.c,v
retrieving revision 1.110
diff -u -p -r1.110 info.c
--- dlls/winspool/info.c 5 Jul 2005 11:00:09 -0000 1.110
+++ dlls/winspool/info.c 6 Jul 2005 13:05:59 -0000
@@ -52,6 +52,7 @@
#include "wine/windef16.h"
#include "wine/unicode.h"
#include "wine/debug.h"
+#include "wine/list.h"
#include "heap.h"
#include "winnls.h"
@@ -68,10 +69,18 @@ static CRITICAL_SECTION printer_handles_
typedef struct {
LPWSTR name;
+ struct list jobs;
} opened_printer_t;
+typedef struct {
+ struct list entry;
+ DWORD job_id;
+ WCHAR *filename;
+} job_t;
+
static opened_printer_t **printer_handles;
static int nb_printer_handles;
+static long next_job_id = 1;
static DWORD (WINAPI *GDI_CallDeviceCapabilities16)( LPCSTR lpszDevice, LPCSTR lpszPort,
WORD fwCapability, LPSTR lpszOutput,
@@ -565,6 +574,7 @@ void WINSPOOL_LoadSystemPrinters(void)
static HANDLE get_opened_printer_entry( LPCWSTR name )
{
UINT handle;
+ opened_printer_t *printer;
EnterCriticalSection(&printer_handles_cs);
@@ -578,7 +588,7 @@ static HANDLE get_opened_printer_entry(
if (printer_handles)
new_array = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, printer_handles,
(nb_printer_handles + 16) * sizeof(*new_array) );
- else
+ else
new_array = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
(nb_printer_handles + 16) * sizeof(*new_array) );
@@ -591,15 +601,17 @@ static HANDLE get_opened_printer_entry(
nb_printer_handles += 16;
}
- if (!(printer_handles[handle] = HeapAlloc(GetProcessHeap(), 0, sizeof(**printer_handles))))
+ if (!(printer = HeapAlloc(GetProcessHeap(), 0, sizeof(*printer))))
{
handle = 0;
goto end;
}
- printer_handles[handle]->name = HeapAlloc(GetProcessHeap(), 0, (strlenW(name) + 1) * sizeof(WCHAR));
- strcpyW(printer_handles[handle]->name, name);
+ printer->name = HeapAlloc(GetProcessHeap(), 0, (strlenW(name) + 1) * sizeof(WCHAR));
+ strcpyW(printer->name, name);
+ list_init(&printer->jobs);
+ printer_handles[handle] = printer;
handle++;
end:
LeaveCriticalSection(&printer_handles_cs);
@@ -1178,23 +1190,96 @@ BOOL WINAPI AddFormW(HANDLE hPrinter, DW
/*****************************************************************************
* AddJobA [WINSPOOL.@]
*/
-BOOL WINAPI AddJobA(HANDLE hPrinter, DWORD Level, LPBYTE pData,
- DWORD cbBuf, LPDWORD pcbNeeded)
+BOOL WINAPI AddJobA(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeeded)
{
- FIXME("(%p,%ld,%p,%ld,%p): stub\n", hPrinter, Level, pData, cbBuf,
- pcbNeeded);
- return 1;
+ BOOL ret;
+ BYTE buf[MAX_PATH * sizeof(WCHAR) + sizeof(ADDJOB_INFO_1W)];
+ DWORD needed;
+
+ if(Level != 1) {
+ SetLastError(ERROR_INVALID_LEVEL);
+ return FALSE;
+ }
+
+ ret = AddJobW(hPrinter, Level, buf, sizeof(buf), &needed);
+
+ if(ret) {
+ ADDJOB_INFO_1W *addjobW = (ADDJOB_INFO_1W*)buf;
+ DWORD len = WideCharToMultiByte(CP_ACP, 0, addjobW->Path, -1, NULL, 0, NULL, NULL);
+ *pcbNeeded = len + sizeof(ADDJOB_INFO_1A);
+ if(*pcbNeeded > cbBuf) {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ ret = FALSE;
+ } else {
+ ADDJOB_INFO_1A *addjobA = (ADDJOB_INFO_1A*)pData;
+ addjobA->JobId = addjobW->JobId;
+ addjobA->Path = (char *)(addjobA + 1);
+ WideCharToMultiByte(CP_ACP, 0, addjobW->Path, -1, addjobA->Path, len, NULL, NULL);
+ }
+ }
+ return ret;
}
/*****************************************************************************
* AddJobW [WINSPOOL.@]
*/
-BOOL WINAPI AddJobW(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf,
- LPDWORD pcbNeeded)
+BOOL WINAPI AddJobW(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeeded)
{
- FIXME("(%p,%ld,%p,%ld,%p): stub\n", hPrinter, Level, pData, cbBuf,
- pcbNeeded);
- return 1;
+ opened_printer_t *printer;
+ job_t *job;
+ BOOL ret = FALSE;
+ static const WCHAR spool_path[] = {'s','p','o','o','l','\\','P','R','I','N','T','E','R','S','\\',0};
+ static const WCHAR fmtW[] = {'%','s','%','0','5','d','.','S','P','L',0};
+ WCHAR path[MAX_PATH], filename[MAX_PATH];
+ DWORD len;
+ ADDJOB_INFO_1W *addjob;
+
+ TRACE("(%p,%ld,%p,%ld,%p)\n", hPrinter, Level, pData, cbBuf, pcbNeeded);
+
+ EnterCriticalSection(&printer_handles_cs);
+
+ printer = get_opened_printer(hPrinter);
+
+ if(!printer) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ goto end;
+ }
+
+ if(Level != 1) {
+ SetLastError(ERROR_INVALID_LEVEL);
+ goto end;
+ }
+
+ job = HeapAlloc(GetProcessHeap(), 0, sizeof(*job));
+ if(!job)
+ goto end;
+
+ job->job_id = InterlockedIncrement(&next_job_id);
+
+ len = GetSystemDirectoryW(path, sizeof(path) / sizeof(WCHAR));
+ if(path[len - 1] != '\\')
+ path[len++] = '\\';
+ memcpy(path + len, spool_path, sizeof(spool_path));
+ sprintfW(filename, fmtW, path, job->job_id);
+
+ len = strlenW(filename);
+ job->filename = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
+ memcpy(job->filename, filename, (len + 1) * sizeof(WCHAR));
+ list_add_tail(&printer->jobs, &job->entry);
+
+ *pcbNeeded = (len + 1) * sizeof(WCHAR) + sizeof(*addjob);
+ if(*pcbNeeded <= cbBuf) {
+ addjob = (ADDJOB_INFO_1W*)pData;
+ addjob->JobId = job->job_id;
+ addjob->Path = (WCHAR *)(addjob + 1);
+ memcpy(addjob->Path, filename, (len + 1) * sizeof(WCHAR));
+ ret = TRUE;
+ } else
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+
+end:
+ LeaveCriticalSection(&printer_handles_cs);
+ return ret;
}
/*****************************************************************************
@@ -1480,26 +1565,30 @@ BOOL WINAPI ClosePrinter(HANDLE hPrinter
{
int i = (int)hPrinter;
opened_printer_t *printer = NULL;
+ BOOL ret = FALSE;
TRACE("Handle %p\n", hPrinter);
EnterCriticalSection(&printer_handles_cs);
if ((i > 0) && (i <= nb_printer_handles))
- {
printer = printer_handles[i - 1];
- printer_handles[i - 1] = NULL;
- }
-
- LeaveCriticalSection(&printer_handles_cs);
if(printer)
{
+ struct list *cursor, *cursor2;
+ LIST_FOR_EACH_SAFE(cursor, cursor2, &printer->jobs)
+ {
+ job_t *job = LIST_ENTRY(cursor, job_t, entry);
+ ScheduleJob(hPrinter, job->job_id);
+ }
HeapFree(GetProcessHeap(), 0, printer->name);
HeapFree(GetProcessHeap(), 0, printer);
- return TRUE;
+ printer_handles[i - 1] = NULL;
+ ret = TRUE;
}
- return FALSE;
+ LeaveCriticalSection(&printer_handles_cs);
+ return ret;
}
/*****************************************************************************
@@ -4518,6 +4607,37 @@ BOOL WINAPI GetJobW(HANDLE hPrinter, DWO
*/
BOOL WINAPI ScheduleJob( HANDLE hPrinter, DWORD dwJobID )
{
- FIXME("Stub: %p %lx\n", hPrinter, dwJobID);
- return FALSE;
+ opened_printer_t *printer;
+ BOOL ret = FALSE;
+ struct list *cursor, *cursor2;
+
+ TRACE("(%p, %lx)\n", hPrinter, dwJobID);
+ EnterCriticalSection(&printer_handles_cs);
+ printer = get_opened_printer(hPrinter);
+ if(!printer)
+ goto end;
+
+ LIST_FOR_EACH_SAFE(cursor, cursor2, &printer->jobs)
+ {
+ job_t *job = LIST_ENTRY(cursor, job_t, entry);
+ HANDLE hf;
+
+ if(job->job_id != dwJobID) continue;
+
+ hf = CreateFileW(job->filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if(hf != INVALID_HANDLE_VALUE)
+ {
+ FIXME("need to schedule job %ld filename %s\n", job->job_id, debugstr_w(job->filename));
+ CloseHandle(hf);
+ DeleteFileW(job->filename);
+ }
+ list_remove(cursor);
+ HeapFree(GetProcessHeap(), 0, job->filename);
+ HeapFree(GetProcessHeap(), 0, job);
+ ret = TRUE;
+ break;
+ }
+end:
+ LeaveCriticalSection(&printer_handles_cs);
+ return ret;
}
More information about the wine-patches
mailing list