|
|
1.1 root 1:
2: /******************************************************************************\
3: * This is a part of the Microsoft Source Code Samples.
4: * Copyright (C) 1993 Microsoft Corporation.
5: * All rights reserved.
6: * This source code is only intended as a supplement to
7: * Microsoft Development Tools and/or WinHelp documentation.
8: * See these sources for detailed information regarding the
9: * Microsoft samples programs.
10: \******************************************************************************/
11:
12: /*
13: ddeinst.c
14: */
15:
16: #include <windows.h>
17: #include "ddeinst.h"
18: #include "ddextrn.h"
19:
20: #include <stdio.h>
21: #include <string.h>
22:
23: extern CONVCONTEXT CCFilter;
24:
25: /********************************************************************
26:
27: StartTraverseThread
28:
29: Function that starts thread to traverse the specified directory.
30:
31: ********************************************************************/
32: BOOL StartTraverseThread (LPSTR lpArg) {
33: HANDLE hThread;
34: LONG lThreadId;
35:
36: hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) TraversePath,
37: lpArg, CREATE_SUSPENDED | STANDARD_RIGHTS_REQUIRED, &lThreadId);
38: if (hThread) {
39: // SetThreadPriority (hThread, THREAD_PRIORITY_BELOW_NORMAL);
40: ResumeThread(hThread);
41:
42: /* Close the handle since we don't need it anymore */
43:
44: CloseHandle (hThread);
45: return (TRUE);
46: }/*endIf*/
47: return (FALSE);
48: }/* end StartTraverseThread */
49:
50:
51: int iRecurse = 0;
52:
53: /********************************************************************
54:
55: TraversePath
56:
57: Function that recursively descends a specified directory looking
58: for files that have the .exe extension.
59:
60: ********************************************************************/
61:
62: BOOL TraversePath (LPSTR szPath) {
63: HANDLE hSearch;
64: WIN32_FIND_DATA findData;
65: LPSTR szTemp;
66: LPSTR szNewPath;
67: LPSTR szTempName;
68: LPSTR szFullPath;
69: int iLen;
70: long lError;
71: long lPos;
72: long lTemp;
73: long lNewPath;
74:
75: // If there is no path then we need to exit.
76: if (!szPath || (strlen (szPath) > (MAX_PATH - 5))) {
77: return (FALSE);
78: }/*endIf*/
79:
80: // Increment the recursion level.
81: iRecurse++;
82:
83: // Get the length of the path plus room for the wildcard and nul.
84: lTemp = strlen (szPath) + 5;
85:
86: // allocate some memory
87: szTemp = VirtualAlloc (NULL, lTemp, MEM_COMMIT, PAGE_READWRITE);
88:
89: // Append the wildcard
90: sprintf (szTemp, "%s\\*.*", szPath);
91:
92: // Look for a file
93: hSearch = FindFirstFile (szTemp, &findData);
94:
95: // If nothing found then return.
96: if (!hSearch || hSearch == (HANDLE) -1) {
97: VirtualFree (szTemp, lTemp, MEM_DECOMMIT);
98: iRecurse--;
99: return (FALSE);
100: }/*endIf*/
101:
102: // Loop through the current directory looking for exectuables.
103: do {
104: if (strcmp (findData.cFileName, ".") &&
105: strcmp (findData.cFileName, "..")) {
106:
107: // Ignore '.' and '..'
108: if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
109:
110: // If it is a directory then recurse.
111:
112: lNewPath = strlen (szPath) + strlen (findData.cFileName) + 1;
113: szNewPath = VirtualAlloc (NULL, lNewPath, MEM_COMMIT,
114: PAGE_READWRITE);
115: sprintf (szNewPath, "%s\\%s", szPath, findData.cFileName);
116: TraversePath (szNewPath);
117: VirtualFree (szNewPath, lNewPath, MEM_DECOMMIT);
118: } else {
119:
120: // See if it ends in .exe
121:
122: iLen = strlen (findData.cFileName) - 4;
123: szTempName = findData.cFileName + iLen;
124: if (!strnicmp (szTempName, ".exe", 4)) {
125:
126: // Add the file name to the list of files.
127:
128: if (!(lPos = SendMessage (hwndFileList, LB_ADDSTRING,
129: (WPARAM) NULL, (LPARAM) findData.cFileName))) {
130:
131: // Debugging code
132:
133: lError = GetLastError ();
134: }/*endIf*/
135: szTempName = VirtualAlloc (NULL, iLen + 4, MEM_COMMIT,
136: PAGE_READWRITE);
137: strncpy (szTempName, findData.cFileName, iLen);
138:
139: // Add the constructed file name to the list of names
140:
141: SendMessage (hwndFileList2, LB_INSERTSTRING, (WPARAM) lPos,
142: (LPARAM) szTempName);
143: VirtualFree (szTempName, iLen + 4, MEM_DECOMMIT);
144: iLen = strlen (szPath) + iLen + 4;
145:
146: // Construct a full pathname to the file.
147:
148: szFullPath = VirtualAlloc (NULL, iLen, MEM_COMMIT,
149: PAGE_READWRITE);
150: sprintf (szFullPath, "%s\\%s", szPath, findData.cFileName);
151:
152: // Add the full path to the hidden list.
153:
154: SendMessage (hwndPathList, LB_INSERTSTRING, (WPARAM) lPos,
155: (LPARAM) szFullPath);
156: VirtualFree (szFullPath, iLen, MEM_DECOMMIT);
157: }/*endIf*/
158: }/*endIf*/
159: }/*endIf*/
160:
161: // Keep looping until no more files.
162:
163: } while (FindNextFile (hSearch, &findData));
164:
165: // End the search.
166:
167: FindClose (hSearch);
168: VirtualFree (szTemp, lTemp, MEM_DECOMMIT);
169:
170: // Decrement the recursion count.
171:
172: iRecurse--;
173: if (!iRecurse) {
174:
175: // If recursion count == 0 then we are done so inform the primary thread.
176:
177: PostMessage (ghwndMain, WM_USER_THREAD_DONE, 0, 0L);
178: }/*endIf*/
179: return (TRUE);
180: }/* end TraversePath */
181:
182: /********************************************************************
183:
184: StartGroupRetrievalThread
185:
186: Function that starts thread to retrieve the names of existing groups
187: from the Program Manager.
188:
189: ********************************************************************/
190:
191:
192: BOOL StartGroupRetrievalThread () {
193: HANDLE hThread;
194: LONG lThreadId;
195:
196: hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) GroupRetrieval,
197: "test", CREATE_SUSPENDED | STANDARD_RIGHTS_REQUIRED, &lThreadId);
198: if (hThread) {
199: SetThreadPriority (hThread, THREAD_PRIORITY_BELOW_NORMAL);
200: ResumeThread (hThread);
201:
202: /* Close the handle since we don't need it anymore */
203:
204: CloseHandle (hThread);
205: return (TRUE);
206: }/*endIf*/
207: return (FALSE);
208: }/* end StartGroupRetrievalThread */
209:
210:
211: // Prototype for DDECallback function.
212: HDDEDATA CALLBACK GroupDDECallback (UINT, UINT, HANDLE, HSZ, HSZ, HDDEDATA,
213: LONG, LONG);
214:
215:
216: /********************************************************************
217:
218: GroupRetrieval
219: Function to obtain the names of all of the defined program groups in
220: the Program Manager.
221:
222: ********************************************************************/
223:
224: BOOL GroupRetrieval (LPSTR lpDummy) {
225: LPBYTE lpByte;
226: LPSTR szGroups;
227: LPSTR szToken;
228: LPSTR szMem;
229: LPSTR szToken2;
230: long lResult;
231: LONG lIdLocal;
232: CRITICAL_SECTION lpCritical;
233: HCONV hConv;
234: HDDEDATA hDdeData;
235: HSZ szProgMan;
236: HSZ szTopic;
237:
238:
239: // Initialize the Dde id to 0
240:
241: lIdLocal = 0L;
242: szGroups = NULL;
243:
244: // Attempt to initialize a conversation.
245:
246: if (DdeInitialize (&lIdLocal, (PFNCALLBACK) GroupDDECallback,
247: (DWORD) APPCMD_CLIENTONLY, 0L)) {
248: return (FALSE);
249: }/*endIf*/
250:
251: // Start a critical section. This fixes a problem where the DDEML
252: // Can hang under threaded conditions.
253:
254: InitializeCriticalSection (&lpCritical);
255: EnterCriticalSection (&lpCritical);
256:
257: // Create a string handle for the Dde conversation.
258:
259: szProgMan = DdeCreateStringHandle (lIdLocal, "PROGMAN", CP_WINANSI);
260:
261: // Connect to the program manager.
262:
263: hConv = DdeConnect (lIdLocal, szProgMan, szProgMan, &CCFilter);
264:
265: PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0, ID_DDEML_CONNECT);
266:
267: // Create a handle for the Group topic.
268:
269: szTopic = DdeCreateStringHandle (lIdLocal, "Groups", CP_WINANSI);
270:
271: // Execute a request for the group names.
272:
273: hDdeData = DdeClientTransaction (NULL, 0L, hConv, szTopic, CF_TEXT,
274: XTYP_REQUEST, 1000, &lResult);
275:
276: PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0, ID_DDEML_RETRIEVING);
277: // Release the two string handles.
278:
279: DdeFreeStringHandle (lIdLocal, szProgMan);
280: DdeFreeStringHandle (lIdLocal, szTopic);
281:
282: // Disconnect the conversation.
283:
284: DdeDisconnect (hConv);
285:
286: PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0, ID_DDEML_COMPLETE);
287:
288: // Exit and delete the critical section.
289:
290: LeaveCriticalSection (&lpCritical);
291: DeleteCriticalSection (&lpCritical);
292:
293: // Verify that we got something back.
294:
295: if (hDdeData && (hDdeData != TRUE)) {
296:
297: // Access the data to get a character pointer.
298:
299: lpByte = DdeAccessData (hDdeData, &lResult);
300:
301: // allocate a block of memory to use.
302:
303: szGroups = szMem = VirtualAlloc (NULL, lResult, MEM_COMMIT,
304: PAGE_READWRITE);
305: if (!szMem) {
306: lResult = GetLastError ();
307: } else {
308:
309: // Copy the Dde data to our own block.
310:
311: memcpy (szGroups, lpByte, lResult);
312: }/*endIf*/
313:
314: // Free the Dde data that is there. This is our responsibility.
315:
316: DdeUnaccessData (hDdeData);
317: DdeFreeDataHandle (hDdeData);
318: }/*endIf*/
319:
320: // If we have a memory block then parse it.
321:
322: if (szMem != NULL) {
323:
324: // Search for 'cr'.
325:
326: szToken = strtok (szGroups, "\n");
327:
328: // While we have a token use it.
329:
330: while (szToken) {
331:
332: // We have to strip out line feeds.
333:
334: if (szToken2 = strrchr (szToken, 0x0d)) {
335: *szToken2 = '\0';
336: }/*endIf*/
337:
338: // Add the resulting string to the combo box of groups.
339:
340: SendMessage (hwndCombo, CB_ADDSTRING, (WPARAM) 0, (LPARAM) szToken);
341:
342: // Find the next 'cr'.
343:
344: szToken = strtok (NULL, "\n");
345: }/*endWhile*/
346:
347: // Release the memory block.
348:
349: VirtualFree (szMem, lResult, MEM_DECOMMIT);
350: }/*endIf*/
351:
352: // If there is a default name defined then use it. And enable the AddGroup
353: // Button.
354:
355: if (strlen (szUserGroup)) {
356: SetWindowText (hwndCombo, szUserGroup);
357: EnableWindow (hwndAddGroupButton, TRUE);
358: } else {
359:
360: // There is no default group so disable the button.
361:
362: EnableWindow (hwndAddGroupButton, FALSE);
363: }/*endIf*/
364:
365: // Release the DDEML.
366:
367: DdeUninitialize (lIdLocal);
368:
369: // Inform the primary thread that the group retrieval is completed.
370:
371: PostMessage (ghwndMain, WM_USER_THREAD_DONE, 0, 0L);
372: return (TRUE);
373: }/* end GroupRetrieval */
374:
375:
376: /********************************************************************
377:
378: GroupDDECallback.
379:
380: Function exists for compatibility. Does nothing.
381:
382: ********************************************************************/
383:
384: HDDEDATA CALLBACK GroupDDECallback (UINT uiType, UINT uiFmt, HANDLE hConv,
385: HSZ sz1, HSZ sz2, HDDEDATA hData, LONG lData1, LONG lData2) {
386: switch (uiType) {
387:
388: }/*endSwitch*/
389: return ((HDDEDATA) NULL);
390: }/* end GroupDDECallback */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.