1#define PRINTDRIVER 2 3#include "stdafx.h" 4 5#include "beCompat.h" 6#include "betalk.h" 7#include "authentication.h" 8#include "printing.h" 9 10#include "string.h" 11#include "winspool.h" 12#include "stdio.h" 13 14 15extern void btMakePath(char *path, char *dir, char *file); 16extern bt_printer *btFindPrinter(char *printerName); 17 18DWORD WINAPI printerThread(LPVOID data); 19void CheckPrintJobStatus(bt_printer *printer, char *printJob); 20bool PrintFile(bt_printer *printer, char *jobName, char *filename); 21 22 23// printerThread() 24// 25DWORD WINAPI printerThread(LPVOID data) 26{ 27 bt_printer *printer = (bt_printer *) data; 28 struct _finddata_t fileInfo; 29 char search[B_PATH_NAME_LENGTH], path[B_PATH_NAME_LENGTH]; 30 long int result, finder; 31 32 if (!data) 33 return 0; 34 35 // Create the search path for all .job files in the spool folder. 36 btMakePath(search, printer->spoolDir, "*.job"); 37 38 while (!printer->killed) 39 { 40 // Find the first print job. 41 finder = result = _findfirst(search, &fileInfo); 42 while (result != -1) 43 { 44 // Create the fully-qualified path to this print job file, then check 45 // its status. 46 btMakePath(path, printer->spoolDir, fileInfo.name); 47 CheckPrintJobStatus(printer, path); 48 49 // Get the next print job. 50 result = _findnext(finder, &fileInfo); 51 } 52 53 // Close our job search and wait awhile. 54 _findclose(finder); 55 Sleep(2000); 56 } 57 58 return 0; 59} 60 61// CheckPrintJobStatus() 62// 63void CheckPrintJobStatus(bt_printer *printer, char *printJob) 64{ 65 char dataPath[B_PATH_NAME_LENGTH], dataFile[B_FILE_NAME_LENGTH]; 66 char jobName[B_FILE_NAME_LENGTH], status[50]; 67 68 GetPrivateProfileString("PrintJob", "Status", "", status, sizeof(status), printJob); 69 70 if (stricmp(status, "Scheduling...") == 0) 71 { 72 // Move status from scheduling to printing. 73 WritePrivateProfileString("PrintJob", "Status", "Printing...", printJob); 74 75 // Get the name of the spooled file and print it. 76 GetPrivateProfileString("PrintJob", "JobName", "", jobName, sizeof(jobName), printJob); 77 GetPrivateProfileString("PrintJob", "DataFile", "", dataFile, sizeof(dataFile), printJob); 78 btMakePath(dataPath, printer->spoolDir, dataFile); 79 PrintFile(printer, jobName, dataPath); 80 81 // Remove the job and data files. 82 remove(dataPath); 83 remove(printJob); 84 } 85} 86 87// PrintFile() 88// 89bool PrintFile(bt_printer *printer, char *jobName, char *fileName) 90{ 91 HANDLE hPrinter; 92 DOC_INFO_1 docInfo; 93 DWORD dwJob, bytesSent; 94 size_t bytes; 95 96 // Allocate a buffer for print data. 97 char *buffer = (char *) malloc(BT_MAX_IO_BUFFER + 1); 98 if (!buffer) 99 return false; 100 101 // Open the file for reading 102 FILE *fp = fopen(fileName, "rb"); 103 if (!fp) 104 { 105 free(buffer); 106 return false; 107 } 108 109 // Need a handle to the printer. 110 if (OpenPrinter(printer->deviceName, &hPrinter, NULL)) 111 { 112 // Fill in the structure with info about this "document." 113 docInfo.pDocName = jobName; 114 docInfo.pOutputFile = NULL; 115 docInfo.pDatatype = "RAW"; 116 117 // Inform the spooler the document is beginning. 118 if ((dwJob = StartDocPrinter(hPrinter, 1, (unsigned char *) &docInfo)) != 0) 119 { 120 // Start a page. 121 if (StartPagePrinter(hPrinter)) 122 { 123 // Send the data to the printer. 124 // Print the file 8K at a time, until we are finished or shut down. 125 while (!printer->killed) 126 { 127 bytes = fread(buffer, 1, BT_MAX_IO_BUFFER, fp); 128 if (bytes <= 0) 129 break; 130 131 if (!WritePrinter(hPrinter, buffer, bytes, &bytesSent)) 132 break; 133 } 134 135 EndPagePrinter(hPrinter); 136 } 137 138 EndDocPrinter(hPrinter); 139 } 140 141 ClosePrinter(hPrinter); 142 } 143 144 if (ferror(fp)) 145 clearerr(fp); 146 147 fclose(fp); 148 free(buffer); 149 return true; 150} 151 152// btPrintJobNew() 153// 154int btPrintJobNew(char *printerName, char *user, char *password, int client_s_addr, char *jobName, char *jobId) 155{ 156 char printJob[B_PATH_NAME_LENGTH], dataFile[B_PATH_NAME_LENGTH], addr[40]; 157 bt_printer *printer = btFindPrinter(printerName); 158 bt_user_rights *ur; 159 char *groups[MAX_GROUPS_PER_USER]; 160 int i, rights; 161 bool authenticated = false; 162 163 // Create a new print job by writing the <jobId>.job file and by 164 // creating the <jobId>.prn file. 165 if (printer) 166 { 167 SYSTEMTIME st; 168 int docId = 0; 169 170 // Verify the user has permission to print. 171 if (printer->security != BT_AUTH_NONE) 172 { 173 // Authenticate the user with name/password. 174 authenticated = authenticateUser(user, password); 175 if (!authenticated) 176 return BEOS_EACCES; 177 178 // Does the authenticated user have any rights on this file share? 179 rights = 0; 180 for (ur = printer->rights; ur; ur = ur->next) 181 if (!ur->isGroup && stricmp(ur->user, user) == 0) 182 rights |= ur->rights; 183 184 // Does the authenticated user belong to any groups that have any rights on this 185 // file share? 186 for (i = 0; i < MAX_GROUPS_PER_USER; i++) 187 groups[i] = NULL; 188 189 getUserGroups(user, groups); 190 for (ur = printer->rights; ur; ur = ur->next) 191 if (ur->isGroup) 192 for (i = 0; i < MAX_GROUPS_PER_USER; i++) 193 if (groups[i] && stricmp(ur->user, groups[i]) == 0) 194 { 195 rights |= ur->rights; 196 break; 197 } 198 199 // Free the memory occupied by the group list. 200 for (i = 0; i < MAX_GROUPS_PER_USER; i++) 201 if (groups[i]) 202 free(groups[i]); 203 204 // If no rights have been granted, deny access. 205 if (!(rights & BT_RIGHTS_PRINT)) 206 return BEOS_EACCES; 207 } 208 209 // Create a new job ID. 210 do 211 { 212 GetSystemTime(&st); 213 sprintf(jobId, "%x-%03d-%d", time(NULL), st.wMilliseconds, docId++); 214 sprintf(printJob, "%s\\%s.job", printer->spoolDir, jobId); 215 } while (access(printJob, 0) == 0); 216 217 // Write the job information file. 218 sprintf(dataFile, "%s.prn", jobId); 219 WritePrivateProfileString("PrintJob", "JobName", jobName, printJob); 220 WritePrivateProfileString("PrintJob", "Status", "Queueing...", printJob); 221 WritePrivateProfileString("PrintJob", "DataFile", dataFile, printJob); 222 WritePrivateProfileString("PrintJob", "User", user, printJob); 223 224 uint8 *_s_addr = (uint8 *) &client_s_addr; 225 sprintf(addr, "%d.%d.%d.%d", _s_addr[0], _s_addr[1], _s_addr[2], _s_addr[3]); 226 WritePrivateProfileString("PrintJob", "Source", addr, printJob); 227 228 // Now create the empty data file. 229 sprintf(dataFile, "%s\\%s.prn", printer->spoolDir, jobId); 230// _creat(dataFile, _S_IWRITE); 231 HANDLE hFile = CreateFile(dataFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL); 232 CloseHandle(hFile); 233 234 return B_OK; 235 } 236 237 return BEOS_ENOENT; 238} 239 240// btPrintJobData() 241// 242int btPrintJobData(char *printerName, char *jobId, char *jobData, int dataLen) 243{ 244 char printJob[B_PATH_NAME_LENGTH]; 245 bt_printer *printer = btFindPrinter(printerName); 246 FILE *fp; 247 248 if (printer) 249 { 250 sprintf(printJob, "%s\\%s.job", printer->spoolDir, jobId); 251 if (access(printJob, 0) == 0) 252 { 253 sprintf(printJob, "%s\\%s.prn", printer->spoolDir, jobId); 254 fp = fopen(printJob, "ab"); 255 if (fp) 256 { 257 fwrite(jobData, 1, dataLen, fp); 258 fclose(fp); 259 return B_OK; 260 } 261 262 return BEOS_EACCES; 263 } 264 } 265 266 return BEOS_ENOENT; 267} 268 269// btPrintJobCommit() 270// 271int btPrintJobCommit(char *printerName, char *jobId) 272{ 273 char printJob[B_PATH_NAME_LENGTH]; 274 bt_printer *printer = btFindPrinter(printerName); 275 276 if (printer) 277 { 278 sprintf(printJob, "%s\\%s.job", printer->spoolDir, jobId); 279 if (access(printJob, 0) == 0) 280 { 281 WritePrivateProfileString("PrintJob", "Status", "Scheduling...", printJob); 282 return B_OK; 283 } 284 } 285 286 return BEOS_ENOENT; 287} 288