xref: /reactos/win32ss/user/user32/misc/resources.c (revision ba3f0743)
1 #include <user32.h>
2 
3 WINE_DEFAULT_DEBUG_CHANNEL(resource);
4 
5 #ifndef _CFGMGR32_H_
6 #define CR_SUCCESS                        0x00000000
7 #define CR_OUT_OF_MEMORY                  0x00000002
8 #define CR_INVALID_POINTER                0x00000003
9 #define CR_INVALID_DATA                   0x0000001F
10 #endif
11 
12 typedef DWORD (WINAPI *CMP_REGNOTIFY) (HANDLE, LPVOID, DWORD, PULONG);
13 typedef DWORD (WINAPI *CMP_UNREGNOTIFY) (ULONG );
14 
15 static HINSTANCE hSetupApi = NULL;
16 
17 /**********************************************************************
18  *	LoadStringW		(USER32.@)
19  *	Synced with Wine Staging 1.7.55
20  */
21 INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id,
22                             LPWSTR buffer, INT buflen )
23 {
24     HGLOBAL hmem;
25     HRSRC hrsrc;
26     WCHAR *p;
27     int string_num;
28     int i;
29 
30     TRACE("instance = %p, id = %04x, buffer = %p, length = %d\n",
31           instance, resource_id, buffer, buflen);
32 
33     if(buffer == NULL)
34         return 0;
35 
36     /* Use loword (incremented by 1) as resourceid */
37     hrsrc = FindResourceW( instance, MAKEINTRESOURCEW((LOWORD(resource_id) >> 4) + 1),
38                            (LPWSTR)RT_STRING );
39     if (!hrsrc) return 0;
40     hmem = LoadResource( instance, hrsrc );
41     if (!hmem) return 0;
42 
43     p = LockResource(hmem);
44     string_num = resource_id & 0x000f;
45     for (i = 0; i < string_num; i++)
46 	p += *p + 1;
47 
48     TRACE("strlen = %d\n", (int)*p );
49 
50     /*if buflen == 0, then return a read-only pointer to the resource itself in buffer
51     it is assumed that buffer is actually a (LPWSTR *) */
52     if(buflen == 0)
53     {
54         *((LPWSTR *)buffer) = p + 1;
55         return *p;
56     }
57 
58     i = min(buflen - 1, *p);
59     if (i > 0) {
60 	memcpy(buffer, p + 1, i * sizeof (WCHAR));
61         buffer[i] = 0;
62     } else {
63 	if (buflen > 1) {
64             buffer[0] = 0;
65 	    return 0;
66 	}
67     }
68 
69     TRACE("%s loaded !\n", debugstr_w(buffer));
70     return i;
71 }
72 
73 /**********************************************************************
74  *	LoadStringA	(USER32.@)
75  *	Synced with Wine Staging 1.7.55
76  */
77 INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id, LPSTR buffer, INT buflen )
78 {
79     HGLOBAL hmem;
80     HRSRC hrsrc;
81     DWORD retval = 0;
82 
83     TRACE("instance = %p, id = %04x, buffer = %p, length = %d\n",
84           instance, resource_id, buffer, buflen);
85 
86     if (!buflen) return -1;
87 
88     /* Use loword (incremented by 1) as resourceid */
89     if ((hrsrc = FindResourceW( instance, MAKEINTRESOURCEW((LOWORD(resource_id) >> 4) + 1),
90                                 (LPWSTR)RT_STRING )) &&
91         (hmem = LoadResource( instance, hrsrc )))
92     {
93         const WCHAR *p = LockResource(hmem);
94         unsigned int id = resource_id & 0x000f;
95 
96         while (id--) p += *p + 1;
97 
98         if (buflen != 1)
99             RtlUnicodeToMultiByteN( buffer, buflen - 1, &retval, (PWSTR)(p + 1), *p * sizeof(WCHAR) );
100     }
101     buffer[retval] = 0;
102     TRACE("returning %s\n", debugstr_a(buffer));
103     return retval;
104 }
105 
106 /*
107  * @implemented
108  */
109 HDEVNOTIFY
110 WINAPI
111 RegisterDeviceNotificationW(HANDLE hRecipient,
112                             LPVOID NotificationFilter,
113                             DWORD Flags)
114 {
115     DWORD ConfigRet = 0;
116     CMP_REGNOTIFY RegNotify = NULL;
117     HDEVNOTIFY hDevNotify = NULL;
118 
119     if (hSetupApi == NULL) hSetupApi = LoadLibraryA("SETUPAPI.DLL");
120     if (hSetupApi == NULL) return NULL;
121 
122     RegNotify = (CMP_REGNOTIFY) GetProcAddress(hSetupApi, "CMP_RegisterNotification");
123     if (RegNotify == NULL)
124     {
125         FreeLibrary(hSetupApi);
126         hSetupApi = NULL;
127         return NULL;
128     }
129 
130     ConfigRet  = RegNotify(hRecipient, NotificationFilter, Flags, (PULONG) &hDevNotify);
131     if (ConfigRet != CR_SUCCESS)
132     {
133         switch (ConfigRet)
134         {
135             case CR_OUT_OF_MEMORY:
136                 SetLastError (ERROR_NOT_ENOUGH_MEMORY);
137                 break;
138 
139             case CR_INVALID_POINTER:
140                 SetLastError (ERROR_INVALID_PARAMETER);
141                 break;
142 
143             case CR_INVALID_DATA:
144                 SetLastError (ERROR_INVALID_DATA);
145                 break;
146 
147             default:
148                 SetLastError (ERROR_SERVICE_SPECIFIC_ERROR);
149                 break;
150         }
151     }
152 
153     return hDevNotify;
154 }
155 
156 
157 /*
158  * @implemented
159  */
160 BOOL
161 WINAPI
162 UnregisterDeviceNotification(HDEVNOTIFY Handle)
163 {
164     DWORD ConfigRet = 0;
165     CMP_UNREGNOTIFY UnRegNotify = NULL;
166 
167     if (hSetupApi == NULL) hSetupApi = LoadLibraryA("SETUPAPI.DLL");
168     if (hSetupApi == NULL) return FALSE;
169 
170     UnRegNotify = (CMP_UNREGNOTIFY) GetProcAddress(hSetupApi, "CMP_UnregisterNotification");
171     if (UnRegNotify == NULL)
172     {
173         FreeLibrary(hSetupApi);
174         hSetupApi = NULL;
175         return FALSE;
176     }
177 
178     ConfigRet  = UnRegNotify((ULONG_PTR)Handle );
179     if (ConfigRet != CR_SUCCESS)
180     {
181         switch (ConfigRet)
182         {
183             case CR_INVALID_POINTER:
184                 SetLastError (ERROR_INVALID_PARAMETER);
185                 break;
186 
187             case CR_INVALID_DATA:
188                 SetLastError (ERROR_INVALID_DATA);
189                 break;
190 
191             default:
192                 SetLastError (ERROR_SERVICE_SPECIFIC_ERROR);
193                 break;
194         }
195         return FALSE;
196     }
197 
198     return TRUE;
199 }
200 
201 /* EOF */
202