Ignore:
Timestamp:
Sep 29, 2010, 5:09:55 PM (15 years ago)
Author:
dmik
Message:

Added argcA and argvA (valid only after WinMain() is entered) that may be used by applications to access ANSI versions of command line arguments w/o performing manual command line conversion and parsing. The standard argc and argv arguments, as opposed, are always in the OEM codepage.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/shell32/shell32_main.c

    r10270 r21464  
    4646 * CommandLineToArgvW                   [SHELL32.7]
    4747 */
    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 */
    20054
    20155/*************************************************************************
     
    21771        BOOL IconNotYetLoaded=TRUE;
    21872
    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",
    22074          (flags & SHGFI_PIDL)? "pidl" : path, dwFileAttributes, psfi, psfi->dwAttributes, sizeofpsfi, flags);
    22175
    22276        if ((flags & SHGFI_USEFILEATTRIBUTES) && (flags & (SHGFI_ATTRIBUTES|SHGFI_EXETYPE|SHGFI_PIDL)))
    22377          return FALSE;
    224        
     78
    22579        /* windows initializes this values regardless of the flags */
    22680        psfi->szDisplayName[0] = '\0';
     
    255109         */
    256110
    257           SetFilePointer( hfile, 0, NULL, SEEK_SET ); 
     111          SetFilePointer( hfile, 0, NULL, SEEK_SET );
    258112          ReadFile( hfile, &mz_header, sizeof(mz_header), &len, NULL );
    259113
     
    262116         if ( *(DWORD*)magic      == IMAGE_NT_SIGNATURE )
    263117         {
    264              SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET ); 
     118             SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
    265119             ReadFile( hfile, &nt, sizeof(nt), &len, NULL );
    266120              CloseHandle( hfile );
     
    275129         {
    276130             IMAGE_OS2_HEADER ne;
    277              SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET ); 
     131             SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
    278132             ReadFile( hfile, &ne, sizeof(ne), &len, NULL );
    279133              CloseHandle( hfile );
     
    286140      }
    287141
    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
    290144           the pidl functions fail on not existing file names */
    291145        if (flags & SHGFI_PIDL)
     
    303157          /* note: the attributes in ISF::ParseDisplayName are not implemented */
    304158        }
    305        
     159
    306160        /* get the parent shellfolder */
    307161        if (pidl)
     
    309163          hr = SHBindToParent( pidl, &IID_IShellFolder, (LPVOID*)&psfParent, &pidlLast);
    310164        }
    311        
     165
    312166        /* get the attributes of the child */
    313167        if (SUCCEEDED(hr) && (flags & SHGFI_ATTRIBUTES))
     
    322176        /* get the displayname */
    323177        if (SUCCEEDED(hr) && (flags & SHGFI_DISPLAYNAME))
    324         { 
     178        {
    325179          if (flags & SHGFI_USEFILEATTRIBUTES)
    326180          {
     
    378232            else
    379233              ret = FALSE;
    380              
     234
    381235            IExtractIconA_Release(pei);
    382236          }
     
    416270            {
    417271              psfi->iIcon = 0;
    418             }         
     272            }
    419273          }
    420274          else
    421275          {
    422             if (!(PidlToSicIndex(psfParent, pidlLast, (flags & SHGFI_LARGEICON), 
     276            if (!(PidlToSicIndex(psfParent, pidlLast, (flags & SHGFI_LARGEICON),
    423277              (flags & SHGFI_OPENICON)? GIL_OPENICON : 0, &(psfi->iIcon))))
    424278            {
     
    426280            }
    427281          }
    428           if (ret) 
     282          if (ret)
    429283          {
    430284            ret = (DWORD) ((flags & SHGFI_LARGEICON) ? ShellBigIconList : ShellSmallIconList);
     
    447301        if(pidlLast) SHFree(pidlLast);
    448302#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",
    450304                psfi->hIcon, psfi->iIcon, psfi->dwAttributes, psfi->szDisplayName, psfi->szTypeName, ret);
    451305#endif
    452306        return ret;
    453 } 
     307}
    454308
    455309/*************************************************************************
     
    478332
    479333        HeapFree(GetProcessHeap(), 0, temppath);
    480        
     334
    481335        return ret;
    482336}
     
    512366
    513367        /* clean up hbmMask and hbmColor */
    514         DeleteObject(IconInfo.hbmMask);       
    515         DeleteObject(IconInfo.hbmColor);       
     368        DeleteObject(IconInfo.hbmMask);
     369        DeleteObject(IconInfo.hbmColor);
    516370    }
    517  
     371
    518372    return hDupIcon;
    519373}
    520    
     374
    521375
    522376/*************************************************************************
     
    586440    char old_dir[1024];
    587441
    588   TRACE("File %s, Dir %s\n", 
    589                  (lpFile != NULL?lpFile:"-"), 
     442  TRACE("File %s, Dir %s\n",
     443                 (lpFile != NULL?lpFile:"-"),
    590444                 (lpDirectory != NULL?lpDirectory:"-"));
    591445
     
    682536          case ABM_SETAUTOHIDEBAR:
    683537               SetWindowPos(data->hWnd,HWND_TOP,rec.left+1000,rec.top,
    684                                        width,height,SWP_SHOWWINDOW);         
     538                                       width,height,SWP_SHOWWINDOW);
    685539               return TRUE;
    686540          case ABM_SETPOS:
     
    710564/*************************************************************************
    711565 * SHLoadInProc                         [SHELL32.225]
    712  * Create an instance of specified object class from within 
     566 * Create an instance of specified object class from within
    713567 * the shell process and release it immediately
    714568 */
     
    745599 * ShellExecuteW                        [SHELL32.294]
    746600 * 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 */
     604HINSTANCE WINAPI
    751605ShellExecuteW(
    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,
    757611       INT nShowCmd) {
    758612
     
    875729          { char* pch = Template + strlen(Template) - strlen(__appendix_str);
    876730                        *pch = '\0';
    877                         SendMessageA( GetDlgItem(hWnd, IDC_LISTBOX), LB_ADDSTRING, 
     731                        SendMessageA( GetDlgItem(hWnd, IDC_LISTBOX), LB_ADDSTRING,
    878732                                        (WPARAM)-1, (LPARAM)Template );
    879733                    }
     
    939793
    940794    TRACE("\n");
    941    
     795
    942796    if(!(hRes = FindResourceA(shell32_hInstance, "SHELL_ABOUT_MSGBOX", RT_DIALOGA)))
    943797        return FALSE;
     
    982836HRESULT WINAPI SHELL32_DllGetVersion (DLLVERSIONINFO *pdvi)
    983837{
    984         if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) 
     838        if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
    985839        {
    986840          WARN("wrong DLLVERSIONINFO size from app");
     
    1008862BOOL    (* WINAPI pCOMCTL32_Free) (LPVOID);
    1009863
    1010 /* 2001-10-17 @@@PH 
     864/* 2001-10-17 @@@PH
    1011865   either me or VAC308 seems to be confused here:
    1012866   if complains about redeclaration of the corresponding functions
    1013867   in commctrl.h
    1014    
     868
    1015869   Even more strangely, all variables "pFunction" are automatically
    1016870   percieved as "Function".
     
    1035889
    1036890LONG            shell32_ObjCount = 0;
    1037 HINSTANCE       shell32_hInstance = 0; 
     891HINSTANCE       shell32_hInstance = 0;
    1038892HIMAGELIST      ShellSmallIconList = 0;
    1039893HIMAGELIST      ShellBigIconList = 0;
     
    1058912
    1059913            shell32_hInstance = hinstDLL;
    1060             hComctl32 = GetModuleHandleA("COMCTL32.DLL");       
     914            hComctl32 = GetModuleHandleA("COMCTL32.DLL");
    1061915            DisableThreadLibraryCalls(shell32_hInstance);
    1062916
     
    1110964
    1111965            if ( !shell32_RefCount )
    1112             { 
     966            {
    1113967              shell32_hInstance = 0;
    1114968
    1115               if (pdesktopfolder) 
     969              if (pdesktopfolder)
    1116970              {
    1117971                IShellFolder_Release(pdesktopfolder);
     
    1121975              SIC_Destroy();
    1122976              FreeChangeNotifications();
    1123              
     977
    1124978              /* this one is here to check if AddRef/Release is balanced */
    1125979              if (shell32_ObjCount)
     
    1139993 *
    1140994 * PARAMETERS
    1141  *   
     995 *
    1142996 *    BOOL bInstall - TRUE for install, FALSE for uninstall
    1143997 *    LPCWSTR pszCmdLine - command line (unused by shell32?)
Note: See TracChangeset for help on using the changeset viewer.