|
|
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.