1 #include "windows.h"
2 #include "tchar.h"
3 #include "conio.h"
4 #include "stdio.h"
5
6 #define MY_KEY _T("PathToMyRegistryKey\\MyRegistryKey") // Registry key
7 #define MY_VALUES _T("NameOfTheREG_MULTI_SZListOfValues") // Registry values
8 #define NEW_VALUE _T("MyNewValue") // New value
9 #define FIND_VALUE _T("AnExistingValue") // We will insert the new value after this one
10
11 int _tmain(int argc, _TCHAR* argv[])
12 {
13 LONG lResult = 0;
14 HKEY hKey = NULL;
15 LPTSTR lpValues = NULL;
16 LPTSTR lpValue = NULL;
17 LPTSTR lpNewValues = NULL;
18 LPTSTR lpNewValue = NULL;
19 DWORD cbValues = 0;
20 DWORD cbNewValues = 0;
21 DWORD cbNewValue = 0;
22 BOOL bFound = FALSE;
23
24 __try
25 {
26 // OPEN THE REGISTRY KEY
27 //
28 _tprintf(_T("RegOpenKeyEx..."));
29 lResult = RegOpenKeyEx(
30 HKEY_LOCAL_MACHINE,
31 MY_KEY,
32 0,
33 KEY_ALL_ACCESS,
34 &hKey
35 );
36 if (ERROR_SUCCESS != lResult) { _tprintf(_T("ERROR 0x%x\n"), lResult); return 1; }
37 _tprintf(_T("SUCCESS\n"));
38
39 // READ THE REG_MULTI_SZ VALUES
40 //
41 // Get size of the buffer for the values
42 _tprintf(_T("RegQueryValueEx..."));
43 lResult = RegQueryValueEx(
44 hKey,
45 MY_VALUES,
46 NULL,
47 NULL,
48 NULL,
49 &cbValues
50 );
51 if (ERROR_SUCCESS != lResult) { _tprintf(_T("ERROR 0x%x\n"), lResult); return 1; }
52 _tprintf(_T("SUCCESS\n"));
53
54 // Allocate the buffer
55 _tprintf(_T("malloc..."));
56 lpValues = (LPTSTR)malloc(cbValues);
57 if (NULL == lpValues) { _tprintf(_T("ERROR 0x%x\n"), GetLastError()); return 1; }
58 _tprintf(_T("SUCCESS\n"));
59
60 // Get the values
61 _tprintf(_T("RegQueryValueEx..."));
62 lResult = RegQueryValueEx(
63 hKey,
64 MY_VALUES,
65 NULL,
66 NULL,
67 (LPBYTE)lpValues,
68 &cbValues
69 );
70 if (ERROR_SUCCESS != lResult) { _tprintf(_T("ERROR 0x%x\n"), lResult); return 1; }
71 _tprintf(_T("SUCCESS\n"));
72
73 // SHOW THE VALUES
74 //
75 _tprintf(_T("\n**************************\n"));
76 _tprintf(_T("OLD VALUES\n"));
77 _tprintf(_T("**************************\n\n"));
78 lpValue = lpValues;
79 for (; '\0' != *lpValue; lpValue += _tcslen(lpValue) + 1)
80 {
81 // Show one value
82 _tprintf(_T("%s\n"), lpValue);
83 }
84 _tprintf(_T("\n**************************\n\n"));
85
86 // INSERT A NEW VALUE AFTER A SPECIFIC VALUE IN THE LIST OF VALUES
87 //
88 // Allocate a new buffer for the old values plus the new one
89 _tprintf(_T("malloc..."));
90 cbNewValue = (_tcslen(NEW_VALUE) + 1) * sizeof(TCHAR);
91 cbNewValues = cbValues + cbNewValue;
92 lpNewValues = (LPTSTR)malloc(cbNewValues);
93 if (NULL == lpNewValues) { _tprintf(_T("ERROR 0x%x\n"), GetLastError()); return 1; }
94 _tprintf(_T("SUCCESS\n"));
95
96 // Find the value after which we will insert the new one
97 lpValue = lpValues;
98 lpNewValue = lpNewValues;
99 bFound = FALSE;
100 for (; '\0' != *lpValue; lpValue += _tcslen(lpValue) + 1)
101 {
102 // Copy the current value to the target buffer
103 memcpy(lpNewValue, lpValue, (_tcslen(lpValue) + 1) * sizeof(TCHAR));
104
105 if (0 == _tcscmp(lpValue, FIND_VALUE))
106 {
107 // The current value is the one we wanted to find
108 bFound = TRUE;
109
110 // Copy the new value to the target buffer
111 lpNewValue += _tcslen(lpValue) + 1;
112 memcpy(lpNewValue, NEW_VALUE, (_tcslen(NEW_VALUE) + 1) * sizeof(TCHAR));
113 lpNewValue += _tcslen(NEW_VALUE) + 1;
114 }
115 else
116 {
117 // This is not the value we want, continue to the next one
118 lpNewValue += _tcslen(lpValue) + 1;
119 }
120 }
121 if (!bFound)
122 {
123 // We didn't find the value we wanted. Insert the new value at the end
124 memcpy(lpNewValue, NEW_VALUE, (_tcslen(NEW_VALUE) + 1) * sizeof(TCHAR));
125 lpNewValue += _tcslen(NEW_VALUE) + 1;
126 }
127 *lpNewValue = *lpValue;
128
129 // SHOW THE NEW VALUES
130 //
131 _tprintf(_T("\n**************************\n"));
132 _tprintf(_T("NEW VALUES\n"));
133 _tprintf(_T("**************************\n\n"));
134 lpNewValue = lpNewValues;
135 for (; '\0' != *lpNewValue; lpNewValue += _tcslen(lpNewValue) + 1)
136 {
137 // Show one value
138 _tprintf(_T("%s\n"), lpNewValue);
139 }
140 _tprintf(_T("\n**************************\n\n"));
141
142 // WRITE THE NEW VALUES BACK TO THE KEY
143 //
144 _tprintf(_T("RegSetValueEx..."));
145 lResult = RegSetValueEx(
146 hKey,
147 MY_VALUES,
148 NULL,
149 REG_MULTI_SZ,
150 (LPBYTE)lpNewValues,
151 cbNewValues
152 );
153 if (ERROR_SUCCESS != lResult) { _tprintf(_T("ERROR 0x%x\n"), lResult); return 1; }
154 _tprintf(_T("SUCCESS\n"));
155 }
156 __finally
157 {
158 // Clean up
159 //
160 if (NULL != lpValues) { free(lpValues); }
161 if (NULL != lpNewValues) { free(lpNewValues); }
162 if (NULL != hKey) { RegCloseKey(hKey); }
163
164 //_tprintf(_T("\n<<PRESS ANY KEY>>\n"));
165 //_getch();
166 }
167
168 return 0;
169 }
170
171 // 此模板來自http://blogs.msdn.com/b/alejacma/archive/2009/11/12/how-to-manipulate-reg-multi-sz-values-from-the-registry-c.aspx