win32u: Move cursor clipping functions to input.c.
[wine.git] / programs / services / utils.c
blobdaaf4bb1d5d5f0b8b00cafcc9707ceabde9aaad3
1 /*
2 * Services.exe - some utility functions
4 * Copyright 2007 Google (Mikolaj Zalewski)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define WIN32_LEAN_AND_MEAN
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <windows.h>
26 #include <winsvc.h>
28 #include "wine/debug.h"
29 #include "services.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(service);
33 BOOL check_multisz(LPCWSTR lpMultiSz, DWORD cbSize)
35 if (cbSize == 0 || (cbSize == sizeof(WCHAR) && lpMultiSz[0] == 0))
36 return TRUE;
37 if ((cbSize % sizeof(WCHAR)) != 0 || cbSize < 2*sizeof(WCHAR))
38 return FALSE;
39 if (lpMultiSz[cbSize/2 - 1] || lpMultiSz[cbSize/2 - 2])
40 return FALSE;
41 return TRUE;
44 DWORD load_reg_string(HKEY hKey, LPCWSTR szValue, BOOL bExpand, LPWSTR *output)
46 DWORD size, type;
47 LPWSTR buf = NULL;
48 DWORD err;
50 *output = NULL;
51 if ((err = RegQueryValueExW(hKey, szValue, 0, &type, NULL, &size)) != 0)
53 if (err == ERROR_FILE_NOT_FOUND)
54 return ERROR_SUCCESS;
55 goto failed;
57 if (!(type == REG_SZ || (type == REG_EXPAND_SZ && bExpand)))
59 err = ERROR_INVALID_DATATYPE;
60 goto failed;
62 buf = malloc(size + sizeof(WCHAR));
63 if ((err = RegQueryValueExW(hKey, szValue, 0, &type, (LPBYTE)buf, &size)) != 0)
64 goto failed;
65 buf[size/sizeof(WCHAR)] = 0;
67 if (type == REG_EXPAND_SZ)
69 LPWSTR str;
70 if (!(size = ExpandEnvironmentStringsW(buf, NULL, 0)))
72 err = GetLastError();
73 goto failed;
75 str = malloc(size * sizeof(WCHAR));
76 ExpandEnvironmentStringsW(buf, str, size);
77 free(buf);
78 *output = str;
80 else
81 *output = buf;
82 return ERROR_SUCCESS;
84 failed:
85 WINE_ERR("Error %ld while reading value %s\n", err, wine_dbgstr_w(szValue));
86 free(buf);
87 return err;
90 DWORD load_reg_multisz(HKEY hKey, LPCWSTR szValue, BOOL bAllowSingle, LPWSTR *output)
92 DWORD size, type;
93 LPWSTR buf = NULL;
94 DWORD err;
96 *output = NULL;
97 if ((err = RegQueryValueExW(hKey, szValue, 0, &type, NULL, &size)) != 0)
99 if (err == ERROR_FILE_NOT_FOUND)
101 *output = calloc(1, sizeof(WCHAR));
102 return ERROR_SUCCESS;
104 goto failed;
106 if (!((type == REG_MULTI_SZ) || ((type == REG_SZ) && bAllowSingle)))
108 err = ERROR_INVALID_DATATYPE;
109 goto failed;
111 buf = malloc(size + 2 * sizeof(WCHAR));
112 if ((err = RegQueryValueExW(hKey, szValue, 0, &type, (LPBYTE)buf, &size)) != 0)
113 goto failed;
114 buf[size/sizeof(WCHAR)] = 0;
115 buf[size/sizeof(WCHAR) + 1] = 0;
116 *output = buf;
117 return ERROR_SUCCESS;
119 failed:
120 WINE_ERR("Error %ld while reading value %s\n", err, wine_dbgstr_w(szValue));
121 free(buf);
122 return err;
125 DWORD load_reg_dword(HKEY hKey, LPCWSTR szValue, DWORD *output)
127 DWORD size, type;
128 DWORD err;
130 *output = 0;
131 size = sizeof(DWORD);
132 if ((err = RegQueryValueExW(hKey, szValue, 0, &type, (LPBYTE)output, &size)) != 0)
134 if (err == ERROR_FILE_NOT_FOUND)
135 return ERROR_SUCCESS;
136 goto failed;
138 if ((type != REG_DWORD && type != REG_BINARY) || size != sizeof(DWORD))
140 err = ERROR_INVALID_DATATYPE;
141 goto failed;
143 return ERROR_SUCCESS;
145 failed:
146 WINE_ERR("Error %ld while reading value %s\n", err, wine_dbgstr_w(szValue));
147 return err;