Changeset 21464 for trunk/src/shell32/shell32_main.c
- Timestamp:
- Sep 29, 2010, 5:09:55 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/shell32/shell32_main.c
r10270 r21464 46 46 * CommandLineToArgvW [SHELL32.7] 47 47 */ 48 /************************************************************************* 49 * CommandLineToArgvW[SHELL32.@] 50 * 51 * We must interpret the quotes in the command line to rebuild the argv 52 * array correctly: 53 * - arguments are separated by spaces or tabs 54 * - quotes serve as optional argument delimiters 55 * '"a b"' -> 'a b' 56 * - escaped quotes must be converted back to '"' 57 * '\"' -> '"' 58 * - an odd number of '\'s followed by '"' correspond to half that number 59 * of '\' followed by a '"' (extension of the above) 60 * '\\\"' -> '\"' 61 * '\\\\\"' -> '\\"' 62 * - an even number of '\'s followed by a '"' correspond to half that number 63 * of '\', plus a regular quote serving as an argument delimiter (which 64 * means it does not appear in the result) 65 * 'a\\"b c"' -> 'a\b c' 66 * 'a\\\\"b c"' -> 'a\\b c' 67 * - '\' that are not followed by a '"' are copied literally 68 * 'a\b' -> 'a\b' 69 * 'a\\b' -> 'a\\b' 70 * 71 * Note: 72 * '\t' == 0x0009 73 * ' ' == 0x0020 74 * '"' == 0x0022 75 * '\\' == 0x005c 76 */ 77 LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs) 78 { 79 DWORD argc; 80 HGLOBAL hargv; 81 LPWSTR *argv; 82 LPCWSTR cs; 83 LPWSTR arg,s,d; 84 LPWSTR cmdline; 85 int in_quotes,bcount; 86 87 if (*lpCmdline==0) { 88 /* Return the path to the executable */ 89 DWORD size; 90 91 hargv=0; 92 size=16; 93 do { 94 size*=2; 95 hargv=GlobalReAlloc(hargv, size, 0); 96 argv=GlobalLock(hargv); 97 } while (GetModuleFileNameW((HMODULE)0, (LPWSTR)(argv+1), size-sizeof(LPWSTR)) == 0); 98 argv[0]=(LPWSTR)(argv+1); 99 if (numargs) 100 *numargs=2; 101 102 return argv; 103 } 104 105 /* to get a writeable copy */ 106 argc=0; 107 bcount=0; 108 in_quotes=0; 109 cs=lpCmdline; 110 while (1) { 111 if (*cs==0 || ((*cs==0x0009 || *cs==0x0020) && !in_quotes)) { 112 /* space */ 113 argc++; 114 /* skip the remaining spaces */ 115 while (*cs==0x0009 || *cs==0x0020) { 116 cs++; 117 } 118 if (*cs==0) 119 break; 120 bcount=0; 121 continue; 122 } else if (*cs==0x005c) { 123 /* '\', count them */ 124 bcount++; 125 } else if ((*cs==0x0022) && ((bcount & 1)==0)) { 126 /* unescaped '"' */ 127 in_quotes=!in_quotes; 128 bcount=0; 129 } else { 130 /* a regular character */ 131 bcount=0; 132 } 133 cs++; 134 } 135 /* Allocate in a single lump, the string array, and the strings that go with it. 136 * This way the caller can make a single GlobalFree call to free both, as per MSDN. 137 */ 138 hargv=GlobalAlloc(0, argc*sizeof(LPWSTR)+(strlenW(lpCmdline)+1)*sizeof(WCHAR)); 139 argv=GlobalLock(hargv); 140 if (!argv) 141 return NULL; 142 cmdline=(LPWSTR)(argv+argc); 143 strcpyW(cmdline, lpCmdline); 144 145 argc=0; 146 bcount=0; 147 in_quotes=0; 148 arg=d=s=cmdline; 149 while (*s) { 150 if ((*s==0x0009 || *s==0x0020) && !in_quotes) { 151 /* Close the argument and copy it */ 152 *d=0; 153 argv[argc++]=arg; 154 155 /* skip the remaining spaces */ 156 do { 157 s++; 158 } while (*s==0x0009 || *s==0x0020); 159 160 /* Start with a new argument */ 161 arg=d=s; 162 bcount=0; 163 } else if (*s==0x005c) { 164 /* '\\' */ 165 *d++=*s++; 166 bcount++; 167 } else if (*s==0x0022) { 168 /* '"' */ 169 if ((bcount & 1)==0) { 170 /* Preceeded by an even number of '\', this is half that 171 * number of '\', plus a quote which we erase. 172 */ 173 d-=bcount/2; 174 in_quotes=!in_quotes; 175 s++; 176 } else { 177 /* Preceeded by an odd number of '\', this is half that 178 * number of '\' followed by a '"' 179 */ 180 d=d-bcount/2-1; 181 *d++='"'; 182 s++; 183 } 184 bcount=0; 185 } else { 186 /* a regular character */ 187 *d++=*s++; 188 bcount=0; 189 } 190 } 191 if (*arg) { 192 *d='\0'; 193 argv[argc++]=arg; 194 } 195 if (numargs) 196 *numargs=argc; 197 198 return argv; 199 } 48 /************************************************************************* 49 * CommandLineToArgvW[SHELL32.@] 50 * 51 * NOTE: The procedure is moved to KERNEL32.DLL (wprocess.cpp) and is now simply 52 * re-exported from SHELL32.DLL by importing it from there. 53 */ 200 54 201 55 /************************************************************************* … … 217 71 BOOL IconNotYetLoaded=TRUE; 218 72 219 TRACE("(%s fattr=0x%lx sfi=%p(attr=0x%08lx) size=0x%x flags=0x%x)\n", 73 TRACE("(%s fattr=0x%lx sfi=%p(attr=0x%08lx) size=0x%x flags=0x%x)\n", 220 74 (flags & SHGFI_PIDL)? "pidl" : path, dwFileAttributes, psfi, psfi->dwAttributes, sizeofpsfi, flags); 221 75 222 76 if ((flags & SHGFI_USEFILEATTRIBUTES) && (flags & (SHGFI_ATTRIBUTES|SHGFI_EXETYPE|SHGFI_PIDL))) 223 77 return FALSE; 224 78 225 79 /* windows initializes this values regardless of the flags */ 226 80 psfi->szDisplayName[0] = '\0'; … … 255 109 */ 256 110 257 SetFilePointer( hfile, 0, NULL, SEEK_SET ); 111 SetFilePointer( hfile, 0, NULL, SEEK_SET ); 258 112 ReadFile( hfile, &mz_header, sizeof(mz_header), &len, NULL ); 259 113 … … 262 116 if ( *(DWORD*)magic == IMAGE_NT_SIGNATURE ) 263 117 { 264 SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET ); 118 SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET ); 265 119 ReadFile( hfile, &nt, sizeof(nt), &len, NULL ); 266 120 CloseHandle( hfile ); … … 275 129 { 276 130 IMAGE_OS2_HEADER ne; 277 SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET ); 131 SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET ); 278 132 ReadFile( hfile, &ne, sizeof(ne), &len, NULL ); 279 133 CloseHandle( hfile ); … … 286 140 } 287 141 288 289 /* translate the path into a pidl only when SHGFI_USEFILEATTRIBUTES in not specified 142 143 /* translate the path into a pidl only when SHGFI_USEFILEATTRIBUTES in not specified 290 144 the pidl functions fail on not existing file names */ 291 145 if (flags & SHGFI_PIDL) … … 303 157 /* note: the attributes in ISF::ParseDisplayName are not implemented */ 304 158 } 305 159 306 160 /* get the parent shellfolder */ 307 161 if (pidl) … … 309 163 hr = SHBindToParent( pidl, &IID_IShellFolder, (LPVOID*)&psfParent, &pidlLast); 310 164 } 311 165 312 166 /* get the attributes of the child */ 313 167 if (SUCCEEDED(hr) && (flags & SHGFI_ATTRIBUTES)) … … 322 176 /* get the displayname */ 323 177 if (SUCCEEDED(hr) && (flags & SHGFI_DISPLAYNAME)) 324 { 178 { 325 179 if (flags & SHGFI_USEFILEATTRIBUTES) 326 180 { … … 378 232 else 379 233 ret = FALSE; 380 234 381 235 IExtractIconA_Release(pei); 382 236 } … … 416 270 { 417 271 psfi->iIcon = 0; 418 } 272 } 419 273 } 420 274 else 421 275 { 422 if (!(PidlToSicIndex(psfParent, pidlLast, (flags & SHGFI_LARGEICON), 276 if (!(PidlToSicIndex(psfParent, pidlLast, (flags & SHGFI_LARGEICON), 423 277 (flags & SHGFI_OPENICON)? GIL_OPENICON : 0, &(psfi->iIcon)))) 424 278 { … … 426 280 } 427 281 } 428 if (ret) 282 if (ret) 429 283 { 430 284 ret = (DWORD) ((flags & SHGFI_LARGEICON) ? ShellBigIconList : ShellSmallIconList); … … 447 301 if(pidlLast) SHFree(pidlLast); 448 302 #ifdef MORE_DEBUG 449 TRACE ("icon=0x%08x index=0x%08x attr=0x%08lx name=%s type=%s ret=0x%08lx\n", 303 TRACE ("icon=0x%08x index=0x%08x attr=0x%08lx name=%s type=%s ret=0x%08lx\n", 450 304 psfi->hIcon, psfi->iIcon, psfi->dwAttributes, psfi->szDisplayName, psfi->szTypeName, ret); 451 305 #endif 452 306 return ret; 453 } 307 } 454 308 455 309 /************************************************************************* … … 478 332 479 333 HeapFree(GetProcessHeap(), 0, temppath); 480 334 481 335 return ret; 482 336 } … … 512 366 513 367 /* clean up hbmMask and hbmColor */ 514 DeleteObject(IconInfo.hbmMask); 515 DeleteObject(IconInfo.hbmColor); 368 DeleteObject(IconInfo.hbmMask); 369 DeleteObject(IconInfo.hbmColor); 516 370 } 517 371 518 372 return hDupIcon; 519 373 } 520 374 521 375 522 376 /************************************************************************* … … 586 440 char old_dir[1024]; 587 441 588 TRACE("File %s, Dir %s\n", 589 (lpFile != NULL?lpFile:"-"), 442 TRACE("File %s, Dir %s\n", 443 (lpFile != NULL?lpFile:"-"), 590 444 (lpDirectory != NULL?lpDirectory:"-")); 591 445 … … 682 536 case ABM_SETAUTOHIDEBAR: 683 537 SetWindowPos(data->hWnd,HWND_TOP,rec.left+1000,rec.top, 684 width,height,SWP_SHOWWINDOW); 538 width,height,SWP_SHOWWINDOW); 685 539 return TRUE; 686 540 case ABM_SETPOS: … … 710 564 /************************************************************************* 711 565 * SHLoadInProc [SHELL32.225] 712 * Create an instance of specified object class from within 566 * Create an instance of specified object class from within 713 567 * the shell process and release it immediately 714 568 */ … … 745 599 * ShellExecuteW [SHELL32.294] 746 600 * from shellapi.h 747 * WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpOperation, 748 * LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd); 749 */ 750 HINSTANCE WINAPI 601 * WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpOperation, 602 * LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd); 603 */ 604 HINSTANCE WINAPI 751 605 ShellExecuteW( 752 HWND hwnd, 753 LPCWSTR lpOperation, 754 LPCWSTR lpFile, 755 LPCWSTR lpParameters, 756 LPCWSTR lpDirectory, 606 HWND hwnd, 607 LPCWSTR lpOperation, 608 LPCWSTR lpFile, 609 LPCWSTR lpParameters, 610 LPCWSTR lpDirectory, 757 611 INT nShowCmd) { 758 612 … … 875 729 { char* pch = Template + strlen(Template) - strlen(__appendix_str); 876 730 *pch = '\0'; 877 SendMessageA( GetDlgItem(hWnd, IDC_LISTBOX), LB_ADDSTRING, 731 SendMessageA( GetDlgItem(hWnd, IDC_LISTBOX), LB_ADDSTRING, 878 732 (WPARAM)-1, (LPARAM)Template ); 879 733 } … … 939 793 940 794 TRACE("\n"); 941 795 942 796 if(!(hRes = FindResourceA(shell32_hInstance, "SHELL_ABOUT_MSGBOX", RT_DIALOGA))) 943 797 return FALSE; … … 982 836 HRESULT WINAPI SHELL32_DllGetVersion (DLLVERSIONINFO *pdvi) 983 837 { 984 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) 838 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) 985 839 { 986 840 WARN("wrong DLLVERSIONINFO size from app"); … … 1008 862 BOOL (* WINAPI pCOMCTL32_Free) (LPVOID); 1009 863 1010 /* 2001-10-17 @@@PH 864 /* 2001-10-17 @@@PH 1011 865 either me or VAC308 seems to be confused here: 1012 866 if complains about redeclaration of the corresponding functions 1013 867 in commctrl.h 1014 868 1015 869 Even more strangely, all variables "pFunction" are automatically 1016 870 percieved as "Function". … … 1035 889 1036 890 LONG shell32_ObjCount = 0; 1037 HINSTANCE shell32_hInstance = 0; 891 HINSTANCE shell32_hInstance = 0; 1038 892 HIMAGELIST ShellSmallIconList = 0; 1039 893 HIMAGELIST ShellBigIconList = 0; … … 1058 912 1059 913 shell32_hInstance = hinstDLL; 1060 hComctl32 = GetModuleHandleA("COMCTL32.DLL"); 914 hComctl32 = GetModuleHandleA("COMCTL32.DLL"); 1061 915 DisableThreadLibraryCalls(shell32_hInstance); 1062 916 … … 1110 964 1111 965 if ( !shell32_RefCount ) 1112 { 966 { 1113 967 shell32_hInstance = 0; 1114 968 1115 if (pdesktopfolder) 969 if (pdesktopfolder) 1116 970 { 1117 971 IShellFolder_Release(pdesktopfolder); … … 1121 975 SIC_Destroy(); 1122 976 FreeChangeNotifications(); 1123 977 1124 978 /* this one is here to check if AddRef/Release is balanced */ 1125 979 if (shell32_ObjCount) … … 1139 993 * 1140 994 * PARAMETERS 1141 * 995 * 1142 996 * BOOL bInstall - TRUE for install, FALSE for uninstall 1143 997 * LPCWSTR pszCmdLine - command line (unused by shell32?)
Note:
See TracChangeset
for help on using the changeset viewer.