1 /*
2  * PROJECT:     ReactOS Local Spooler
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     Various tools
5  * COPYRIGHT:   Copyright 2015-2017 Colin Finck (colin@reactos.org)
6  */
7 
8 #include "precomp.h"
9 
10 /**
11  * @name AllocAndRegQueryWSZ
12  *
13  * Queries a REG_SZ value in the registry, allocates memory for it and returns a buffer containing the value.
14  * You have to free this buffer using DllFreeSplMem.
15  *
16  * @param hKey
17  * HKEY variable of the key opened with RegOpenKeyExW.
18  *
19  * @param pwszValueName
20  * Name of the REG_SZ value to query.
21  *
22  * @return
23  * Pointer to the buffer containing the value or NULL in case of failure.
24  */
25 PWSTR
26 AllocAndRegQueryWSZ(HKEY hKey, PCWSTR pwszValueName)
27 {
28     DWORD cbNeeded;
29     LONG lStatus;
30     PWSTR pwszValue;
31 
32     // Determine the size of the required buffer.
33     lStatus = RegQueryValueExW(hKey, pwszValueName, NULL, NULL, NULL, &cbNeeded);
34     if (lStatus != ERROR_SUCCESS)
35     {
36         ERR("RegQueryValueExW failed with status %ld!\n", lStatus);
37         return NULL;
38     }
39 
40     // Allocate it.
41     pwszValue = DllAllocSplMem(cbNeeded);
42     if (!pwszValue)
43     {
44         ERR("DllAllocSplMem failed!\n");
45         return NULL;
46     }
47 
48     // Now get the actual value.
49     lStatus = RegQueryValueExW(hKey, pwszValueName, NULL, NULL, (PBYTE)pwszValue, &cbNeeded);
50     if (lStatus != ERROR_SUCCESS)
51     {
52         ERR("RegQueryValueExW failed with status %ld!\n", lStatus);
53         DllFreeSplMem(pwszValue);
54         return NULL;
55     }
56 
57     return pwszValue;
58 }
59 
60 PDEVMODEW
61 DuplicateDevMode(PDEVMODEW pInput)
62 {
63     PDEVMODEW pOutput;
64 
65     // Allocate a buffer for this DevMode.
66     pOutput = DllAllocSplMem(pInput->dmSize + pInput->dmDriverExtra);
67     if (!pOutput)
68     {
69         ERR("DllAllocSplMem failed!\n");
70         return NULL;
71     }
72 
73     // Copy it.
74     CopyMemory(pOutput, pInput, pInput->dmSize + pInput->dmDriverExtra);
75 
76     return pOutput;
77 }
78 
79 /******************************************************************
80  * copy_servername_from_name  (internal)
81  *
82  * for an external server, the serverpart from the name is copied.
83  *
84  * RETURNS
85  *  the length (in WCHAR) of the serverpart (0 for the local computer)
86  *  (-length), when the name is too long
87  *
88  */
89 LONG copy_servername_from_name(LPCWSTR name, LPWSTR target)
90 {
91     LPCWSTR server;
92     LPWSTR  ptr;
93     WCHAR   buffer[MAX_COMPUTERNAME_LENGTH +1];
94     DWORD   len;
95     DWORD   serverlen;
96 
97     if (target) *target = '\0';
98 
99     if (name == NULL) return 0;
100     if ((name[0] != '\\') || (name[1] != '\\')) return 0;
101 
102     server = &name[2];
103     /* skip over both backslash, find separator '\' */
104     ptr = wcschr(server, '\\');
105     serverlen = (ptr) ? ptr - server : lstrlenW(server);
106 
107     /* servername is empty */
108     if (serverlen == 0) return 0;
109 
110     FIXME("found %s\n", debugstr_wn(server, serverlen));
111 
112     if (serverlen > MAX_COMPUTERNAME_LENGTH) return -(LONG)serverlen;
113 
114     if (target)
115     {
116         memcpy(target, server, serverlen * sizeof(WCHAR));
117         target[serverlen] = '\0';
118     }
119 
120     len = ARRAYSIZE(buffer);
121     if (GetComputerNameW(buffer, &len))
122     {
123         if ((serverlen == len) && (_wcsnicmp(server, buffer, len) == 0))
124         {
125             /* The requested Servername is our computername */
126             return 0;
127         }
128     }
129     return serverlen;
130 }
131