ReactOS  0.4.15-dev-2534-geba00d1
utils.c
Go to the documentation of this file.
1 /*
2 * PROJECT: ReactOS Spooler API
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Utility Functions related to Print Processors
5 * COPYRIGHT: Copyright 2020 Doug Lyons (douglyons@douglyons.com)
6 */
7 
8 #include "precomp.h"
9 #include <shlobj.h>
10 #include <undocshell.h>
11 
12 #include <pseh/pseh2.h>
13 
14 #define MAX_GETPRINTER_SIZE 4096 - MAX_PATH
15 typedef void (WINAPI *PPfpSHChangeNotify)(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2);
16 
17 static HMODULE hShell32 = (HMODULE)-1;
18 
19 
20 /*
21  * Converts an incoming Unicode string to an ANSI string.
22  * It is only useful for "in-place" conversions where the ANSI string goes
23  * back into the same place where the Unicode string came into this function.
24  *
25  * It returns an error code.
26  */
27 // TODO: It seems that many of the functions involving printing could use this.
29 {
30  PSTR pszTemp;
31  DWORD cch;
32 
33  /*
34  * Map the incoming Unicode pwszField string to an ANSI one here so that we can do
35  * in-place conversion. We read the Unicode input and then we write back the ANSI
36  * conversion into the same buffer for use with our GetPrinterDriverA function
37  */
38  PSTR pszField = (PSTR)pwszField;
39 
40  if (!pwszField)
41  {
42  return ERROR_SUCCESS;
43  }
44 
45  cch = wcslen(pwszField);
46  if (cch == 0)
47  {
48  return ERROR_SUCCESS;
49  }
50 
51  pszTemp = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
52  if (!pszTemp)
53  {
54  ERR("HeapAlloc failed!\n");
56  }
57 
58  WideCharToMultiByte(CP_ACP, 0, pwszField, -1, pszTemp, cch + 1, NULL, NULL);
59  StringCchCopyA(pszField, cch + 1, pszTemp);
60 
61  HeapFree(hProcessHeap, 0, pszTemp);
62 
63  return ERROR_SUCCESS;
64 }
65 
66 static int multi_sz_lenW(const WCHAR *str)
67 {
68  const WCHAR *ptr = str;
69  if (!str) return 0;
70  do
71  {
72  ptr += lstrlenW(ptr) + 1;
73  } while (*ptr);
74 
75  return (ptr - str + 1);// * sizeof(WCHAR); wine does this.
76 }
77 
79 {
80  PSTR pszTemp;
81  INT len, lenW;
82  PSTR pszField = (PSTR)pwszzField;
83 
84  lenW = multi_sz_lenW(pwszzField);
85  if (lenW == 0)
86  {
87  return ERROR_SUCCESS;
88  }
89 
90  len = WideCharToMultiByte(CP_ACP, 0, pwszzField, lenW, NULL, 0, NULL, NULL);
91 
92  pszTemp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
93 
94  WideCharToMultiByte(CP_ACP, 0, pwszzField, lenW, pszTemp, len, NULL, NULL);
95 
96  StringCchCopyA(pszField, len, pszTemp);
97 
98  HeapFree(hProcessHeap, 0, pszTemp);
99 
100  return ERROR_SUCCESS;
101 }
102 
103 //
104 // Implement and simplify later.
105 //
106 LONG WINAPI
108 {
109  BOOL Bad = TRUE;
110  LONG Ret;
111  PSPOOLER_HANDLE pHandle;
112 
114 
115  _SEH2_TRY
116  {
117  pHandle = (PSPOOLER_HANDLE)hSpooler;
118  if ( pHandle && pHandle->Sig == SPOOLER_HANDLE_SIG )
119  {
120  Bad = FALSE; // Not bad.
121  }
122  }
124  {
125  }
126  _SEH2_END;
127 
128  Ret = Bad; // Set return Level to 1 if we are BAD.
129 
130  if ( Bad )
131  {
133  ERR("IPH : Printer Handle failed!\n");
134  }
135  else
136  {
137  if ( Close )
138  {
139  if ( pHandle->bShared || pHandle->cCount != 0 )
140  {
141  pHandle->bShared = TRUE;
142  Ret = 2; // Return a high level and we are shared.
143  FIXME("IPH Close : We are shared\n");
144  }
145  else
146  {
147  pHandle->bClosed = TRUE;
148  FIXME("IPH Close : closing.\n");
149  }
150  }
151  }
152 
153  if ( !Ret ) // Need to be Level 0.
154  {
155  pHandle->cCount++;
156  FIXME("IPH : Count %d\n",pHandle->cCount);
157  }
158 
160 
161  // Return Level:
162  // 2 : Close and/or shared
163  // 1 : Failed Handle
164  // 0 : In use.
165  return Ret;
166 }
167 //
168 // This one too.
169 //
170 BOOL WINAPI
172 {
173  BOOL Ret = FALSE;
174  PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hSpooler;
176  if ( pHandle->bShared && --pHandle->cCount == 0 )
177  {
178  pHandle->bClosed = TRUE;
179  pHandle->bShared = FALSE;
180  Ret = TRUE;
181  }
183  FIXME("IUH : Count %d\n",pHandle->cCount);
184  if ( Ret )
185  {
186 // ClosePrinterWorker( pHandle );
187  }
188  return Ret;
189 }
190 
204 AllocSplStr(PCWSTR pwszInput)
205 {
206  DWORD cbInput;
207  PWSTR pwszOutput;
208 
209  // Sanity check
210  if (!pwszInput)
211  return NULL;
212 
213  // Get the length of the input string.
214  cbInput = (wcslen(pwszInput) + 1) * sizeof(WCHAR);
215 
216  // Allocate it. We don't use DllAllocSplMem here, because it unnecessarily zeroes the memory.
217  pwszOutput = HeapAlloc(hProcessHeap, 0, cbInput);
218  if (!pwszOutput)
219  {
220  ERR("HeapAlloc failed!\n");
221  return NULL;
222  }
223 
224  // Copy the string and return it.
225  CopyMemory(pwszOutput, pwszInput, cbInput);
226  return pwszOutput;
227 }
228 
244 {
245  return HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, dwBytes);
246 }
247 
259 BOOL WINAPI
261 {
262  if ( !pMem ) return TRUE;
263  return HeapFree(hProcessHeap, 0, pMem);
264 }
265 
277 BOOL WINAPI
278 DllFreeSplStr(PWSTR pwszString)
279 {
280  if ( pwszString )
281  return HeapFree(hProcessHeap, 0, pwszString);
282  return FALSE;
283 }
284 
286 {
287  PSID sid_group, sid_owner;
288  ACL *sacl, *dacl;
289  BOOL bSet = FALSE, bSetd = FALSE, bSets = FALSE;
290  PSECURITY_DESCRIPTOR absolute_sd, retsd;
291 
292  if ( !IsValidSecurityDescriptor( sd ) )
293  {
294  return NULL;
295  }
296 
298 
299  if ( !GetSecurityDescriptorOwner( sd, &sid_owner, &bSet ) )
300  {
301  return NULL;
302  }
303 
304  SetSecurityDescriptorOwner( &absolute_sd, sid_owner, bSet );
305 
306  if ( !GetSecurityDescriptorGroup( sd, &sid_group, &bSet ) )
307  {
308  return NULL;
309  }
310 
311  SetSecurityDescriptorGroup( &absolute_sd, sid_group, bSet );
312 
313  if ( !GetSecurityDescriptorDacl( sd, &bSetd, &dacl, &bSet ) )
314  {
315  return NULL;
316  }
317 
318  SetSecurityDescriptorDacl( &absolute_sd, bSetd, dacl, bSet );
319 
320  if ( !GetSecurityDescriptorSacl( sd, &bSets, &sacl, &bSet ) )
321  {
322  return(NULL);
323  }
324 
325  SetSecurityDescriptorSacl( &absolute_sd, bSets, sacl, bSet );
326 
327  *size = GetSecurityDescriptorLength( &absolute_sd );
328 
329  retsd = HeapAlloc( GetProcessHeap(), 0, *size );
330 
331  if ( retsd )
332  {
333  if ( !MakeSelfRelativeSD( &absolute_sd, retsd, size ) )
334  {
335  HeapFree( GetProcessHeap(), 0, retsd );
336  retsd = NULL;
337  }
338  }
339 
340  return retsd;
341 }
342 
343 VOID
344 UpdateTrayIcon( HANDLE hPrinter, DWORD JobId )
345 {
346  PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter;
347  SHCNF_PRINTJOB_INFO spji;
349  DWORD cbNeeded;
350  PPfpSHChangeNotify fpFunction;
351 
352  pHandle->bTrayIcon = TRUE;
353 
354  spji.JobId = JobId;
355 
356  if (!GetPrinterW( hPrinter, 1, (PBYTE)&pi1w, MAX_GETPRINTER_SIZE, &cbNeeded) )
357  {
358  ERR("UpdateTrayIcon : GetPrinterW cbNeeded %d\n");
359  return;
360  }
361 
362  if ( hShell32 == (HMODULE)-1 )
363  {
364  hShell32 = LoadLibraryW(L"shell32.dll");
365  }
366 
367  if ( hShell32 )
368  {
369  fpFunction = (PPfpSHChangeNotify)GetProcAddress( hShell32, "SHChangeNotify" );
370 
371  if ( fpFunction )
372  {
373  fpFunction( SHCNE_CREATE, (SHCNF_FLUSHNOWAIT|SHCNF_FLUSH|SHCNF_PRINTJOBW), pi1w->pName , &spji );
374  }
375  }
376  else
377  {
378  ERR("UpdateTrayIcon : No Shell32!\n");
379  }
380 }
LONG WINAPI IntProtectHandle(HANDLE hSpooler, BOOL Close)
Definition: utils.c:107
BOOL WINAPI SetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bSaclPresent, PACL pSacl, BOOL bSaclDefaulted)
Definition: sec.c:351
const uint16_t * PCWSTR
Definition: typedefs.h:57
BOOL WINAPI IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor)
Definition: sec.c:176
BOOL WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor, PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor, LPDWORD lpdwBufferLength)
Definition: sec.c:214
BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bDaclPresent, PACL pDacl, BOOL bDaclDefaulted)
Definition: sec.c:262
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
#define WideCharToMultiByte
Definition: compat.h:111
SECURITY_DESCRIPTOR * get_sd(SECURITY_DESCRIPTOR *sd, DWORD *size)
Definition: utils.c:285
BOOL WINAPI GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbSaclPresent, PACL *pSacl, LPBOOL lpbSaclDefaulted)
Definition: sec.c:146
#define TRUE
Definition: types.h:120
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
Definition: utils.c:243
uint16_t * PWSTR
Definition: typedefs.h:56
#define CP_ACP
Definition: compat.h:109
BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD dwRevision)
Definition: security.c:808
char CHAR
Definition: xmlstorage.h:175
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
BOOL bShared
Definition: precomp.h:47
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
UINT uFlags
Definition: api.c:59
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define lstrlenW
Definition: compat.h:609
int32_t INT
Definition: typedefs.h:58
BOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pGroup, LPBOOL lpbGroupDefaulted)
Definition: sec.c:76
BOOL WINAPI SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID pOwner, BOOL bOwnerDefaulted)
Definition: sec.c:312
_SEH2_TRY
Definition: create.c:4226
#define SPOOLER_HANDLE_SIG
Definition: precomp.h:32
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
DWORD cCount
Definition: precomp.h:52
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define FIXME(fmt,...)
Definition: debug.h:111
static PVOID ptr
Definition: dispmode.c:27
const WCHAR * str
BOOL WINAPI SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID pGroup, BOOL bGroupDefaulted)
Definition: sec.c:288
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:201
#define LoadLibraryW(x)
Definition: compat.h:606
BOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbDaclPresent, PACL *pDacl, LPBOOL lpbDaclDefaulted)
Definition: sec.c:45
WINBOOL WINAPI GetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded)
Definition: printers.c:2504
VOID UpdateTrayIcon(HANDLE hPrinter, DWORD JobId)
Definition: utils.c:344
GLsizeiptr size
Definition: glext.h:5919
#define MAX_GETPRINTER_SIZE
Definition: utils.c:14
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD_PTR Sig
Definition: precomp.h:40
__wchar_t WCHAR
Definition: xmlstorage.h:180
static HMODULE hShell32
Definition: utils.c:17
Definition: security.c:35
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define WINAPI
Definition: msvc.h:6
#define CopyMemory
Definition: winbase.h:1662
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:611
PWSTR WINAPI AllocSplStr(PCWSTR pwszInput)
Definition: utils.c:204
static const WCHAR sd[]
Definition: suminfo.c:287
static const WCHAR L[]
Definition: oid.c:1250
#define SHCNF_FLUSH
Definition: shlobj.h:1767
GLenum GLsizei len
Definition: glext.h:6722
BOOL bClosed
Definition: precomp.h:48
DWORD UnicodeToAnsiInPlace(PWSTR pwszField)
Definition: utils.c:28
DWORD WINAPI GetSecurityDescriptorLength(PSECURITY_DESCRIPTOR)
#define ERR(fmt,...)
Definition: debug.h:110
BOOL WINAPI DllFreeSplMem(PVOID pMem)
Definition: utils.c:260
HANDLE HMODULE
Definition: typedefs.h:77
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
_SEH2_END
Definition: create.c:4400
CRITICAL_SECTION rtlCritSec
Definition: main.c:13
Definition: sacdrv.h:267
BOOL WINAPI GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pOwner, LPBOOL lpbOwnerDefaulted)
Definition: sec.c:103
DWORD UnicodeToAnsiZZInPlace(PWSTR pwszzField)
Definition: utils.c:78
signed char * PSTR
Definition: retypes.h:7
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define SHCNF_PRINTJOBW
Definition: undocshell.h:122
BOOL WINAPI IntUnprotectHandle(HANDLE hSpooler)
Definition: utils.c:171
CONST void * LPCVOID
Definition: windef.h:191
BOOL WINAPI DllFreeSplStr(PWSTR pwszString)
Definition: utils.c:278
#define GetProcAddress(x, y)
Definition: compat.h:612
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define SHCNE_CREATE
Definition: shlobj.h:1730
static int multi_sz_lenW(const WCHAR *str)
Definition: utils.c:66
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
BYTE * PBYTE
Definition: pedump.c:66
struct _SPOOLER_HANDLE * PSPOOLER_HANDLE
#define HeapFree(x, y, z)
Definition: compat.h:594
#define SHCNF_FLUSHNOWAIT
Definition: shlobj.h:1768
BOOL bTrayIcon
Definition: precomp.h:45
void(WINAPI * PPfpSHChangeNotify)(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
Definition: utils.c:15
HANDLE hProcessHeap
Definition: kbswitch.c:25