xref: /reactos/base/applications/mmc/misc.c (revision 40462c92)
1 /*
2  * ReactOS Management Console
3  * Copyright (C) 2006 - 2007 Thomas Weidenmueller
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 
20 #include "precomp.h"
21 
22 INT
23 LengthOfStrResource(IN HINSTANCE hInst,
24                     IN UINT uID)
25 {
26     HRSRC hrSrc;
27     HGLOBAL hRes;
28     LPWSTR lpName, lpStr;
29 
30     if (hInst == NULL)
31     {
32         return -1;
33     }
34 
35     /* There are always blocks of 16 strings */
36     lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1);
37 
38     /* Find the string table block */
39     if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) &&
40         (hRes = LoadResource(hInst, hrSrc)) &&
41         (lpStr = LockResource(hRes)))
42     {
43         UINT x;
44 
45         /* Find the string we're looking for */
46         uID &= 0xF; /* position in the block, same as % 16 */
47         for (x = 0; x < uID; x++)
48         {
49             lpStr += (*lpStr) + 1;
50         }
51 
52         /* Found the string */
53         return (int)(*lpStr);
54     }
55     return -1;
56 }
57 
58 
59 static INT
60 AllocAndLoadString(OUT LPTSTR *lpTarget,
61                    IN HINSTANCE hInst,
62                    IN UINT uID)
63 {
64     INT ln;
65 
66     ln = LengthOfStrResource(hInst,
67                              uID);
68     if (ln++ > 0)
69     {
70         (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED,
71                                          ln * sizeof(TCHAR));
72         if ((*lpTarget) != NULL)
73         {
74             INT Ret;
75             if (!(Ret = LoadString(hInst, uID, *lpTarget, ln)))
76             {
77                 LocalFree((HLOCAL)(*lpTarget));
78             }
79             return Ret;
80         }
81     }
82     return 0;
83 }
84 
85 DWORD
86 LoadAndFormatString(IN HINSTANCE hInstance,
87                     IN UINT uID,
88                     OUT LPTSTR *lpTarget,
89                     ...)
90 {
91     DWORD Ret = 0;
92     LPWSTR lpFormat;
93     va_list lArgs;
94 
95     if (AllocAndLoadString(&lpFormat,
96                            hInstance,
97                            uID) != 0)
98     {
99         va_start(lArgs, lpTarget);
100         /* let's use FormatMessage to format it because it has the ability to allocate
101            memory automatically */
102         Ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
103                             lpFormat,
104                             0,
105                             0,
106                             (LPTSTR)lpTarget,
107                             0,
108                             &lArgs);
109         va_end(lArgs);
110 
111         LocalFree((HLOCAL)lpFormat);
112     }
113 
114     return Ret;
115 }
116