//
pthread_key_t CorUnix::thObjKey;
-#define PROCESS_PELOADER_FILENAME "clix"
-
static WCHAR W16_WHITESPACE[]= {0x0020, 0x0009, 0x000D, 0};
static WCHAR W16_WHITESPACE_DQUOTE[]= {0x0020, 0x0009, 0x000D, '"', 0};
enum FILETYPE
{
FILE_ERROR,/*ERROR*/
- FILE_PE, /*PE/COFF file*/
FILE_UNIX, /*Unix Executable*/
FILE_DIR /*Directory*/
};
LPCSTR applicationGroupId);
static BOOL getFileName(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, PathCharString& lpFileName);
-static char ** buildArgv(LPCWSTR lpCommandLine, PathCharString& lpAppPath, UINT *pnArg, BOOL prependLoader);
+static char ** buildArgv(LPCWSTR lpCommandLine, PathCharString& lpAppPath, UINT *pnArg);
static BOOL getPath(PathCharString& lpFileName, PathCharString& lpPathFileName);
static int checkFileType(LPCSTR lpFileName);
static BOOL PROCEndProcess(HANDLE hProcess, UINT uExitCode, BOOL bTerminateUnconditionally);
palError = ERROR_FILE_NOT_FOUND;
goto InternalCreateProcessExit;
- case FILE_PE: /* PE/COFF file */
- //Get the path name where the PAL DLL was loaded from
- if ( PAL_GetPALDirectoryA( lpFileNamePS ))
- {
- if (lpFileNamePS.Append("/", 1) == FALSE ||
- lpFileNamePS.Append( PROCESS_PELOADER_FILENAME, strlen(PROCESS_PELOADER_FILENAME)) == FALSE)
- {
- ERROR("Append failed!\n");
- palError = ERROR_INTERNAL_ERROR;
- goto InternalCreateProcessExit;
- }
- }
- else
- {
- ASSERT("PAL_GetPALDirectoryA failed to return the"
- "pal installation directory \n");
- palError = ERROR_INTERNAL_ERROR;
- goto InternalCreateProcessExit;
- }
-
- break;
-
case FILE_UNIX: /* Unix binary file */
break; /* nothing to do */
/* build Argument list, lppArgv is allocated in buildArgv function and
requires to be freed */
- lppArgv = buildArgv(lpCommandLine, lpFileNamePS, &nArg, iRet==1);
+ lppArgv = buildArgv(lpCommandLine, lpFileNamePS, &nArg);
/* set the Environment variable */
if (lpEnvironment != NULL)
/* Replace '\' by '/' */
FILEDosToUnixPathA(lpFileName);
-
if (!getPath(lpFileNamePS, lpPathFileName))
{
/* file is not in the path */
}
/*++
-Functions: VAL16 & VAL32
- Byte swapping functions for reading in little endian format files
---*/
-#ifdef BIGENDIAN
-
-static inline USHORT VAL16(USHORT x)
-{
- return ( ((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8) );
-}
-static inline ULONG VAL32(DWORD x)
-{
- return( ((x & 0xFF000000L) >> 24) |
- ((x & 0x00FF0000L) >> 8) |
- ((x & 0x0000FF00L) << 8) |
- ((x & 0x000000FFL) << 24) );
-}
-#else // BIGENDIAN
-// For little-endian machines, do nothing
-static __inline USHORT VAL16(unsigned short x) { return x; }
-static __inline DWORD VAL32(DWORD x){ return x; }
-#endif // BIGENDIAN
-
-static const DWORD IMAGE_DOS_SIGNATURE = 0x5A4D;
-static const DWORD IMAGE_NT_SIGNATURE = 0x00004550;
-static const DWORD IMAGE_SIZEOF_NT_OPTIONAL32_HEADER = 224;
-static const DWORD IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b;
-static const DWORD IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14;
-
-typedef struct _IMAGE_DATA_DIRECTORY {
- DWORD VirtualAddress;
- DWORD Size;
-} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
-
-typedef struct _IMAGE_OPTIONAL_HEADER {
- //
- // Standard fields.
- //
-
- WORD Magic;
- BYTE MajorLinkerVersion;
- BYTE MinorLinkerVersion;
- DWORD SizeOfCode;
- DWORD SizeOfInitializedData;
- DWORD SizeOfUninitializedData;
- DWORD AddressOfEntryPoint;
- DWORD BaseOfCode;
- DWORD BaseOfData;
-
- //
- // NT additional fields.
- //
-
- DWORD ImageBase;
- DWORD SectionAlignment;
- DWORD FileAlignment;
- WORD MajorOperatingSystemVersion;
- WORD MinorOperatingSystemVersion;
- WORD MajorImageVersion;
- WORD MinorImageVersion;
- WORD MajorSubsystemVersion;
- WORD MinorSubsystemVersion;
- DWORD Win32VersionValue;
- DWORD SizeOfImage;
- DWORD SizeOfHeaders;
- DWORD CheckSum;
- WORD Subsystem;
- WORD DllCharacteristics;
- DWORD SizeOfStackReserve;
- DWORD SizeOfStackCommit;
- DWORD SizeOfHeapReserve;
- DWORD SizeOfHeapCommit;
- DWORD LoaderFlags;
- DWORD NumberOfRvaAndSizes;
- IMAGE_DATA_DIRECTORY DataDirectory[16];
-} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
-
-typedef struct _IMAGE_FILE_HEADER {
- WORD Machine;
- WORD NumberOfSections;
- DWORD TimeDateStamp;
- DWORD PointerToSymbolTable;
- DWORD NumberOfSymbols;
- WORD SizeOfOptionalHeader;
- WORD Characteristics;
-} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
-
-typedef struct _IMAGE_NT_HEADERS {
- DWORD Signature;
- IMAGE_FILE_HEADER FileHeader;
- IMAGE_OPTIONAL_HEADER32 OptionalHeader;
-} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
-
-typedef struct _IMAGE_DOS_HEADER { /* DOS .EXE header*/
- WORD e_magic; /* Magic number*/
- WORD e_cblp; /* Bytes on last page of file*/
- WORD e_cp; /* Pages in file*/
- WORD e_crlc; /* Relocations*/
- WORD e_cparhdr; /* Size of header in paragraphs*/
- WORD e_minalloc; /* Minimum extra paragraphs needed*/
- WORD e_maxalloc; /* Maximum extra paragraphs needed*/
- WORD e_ss; /* Initial (relative) SS value*/
- WORD e_sp; /* Initial SP value*/
- WORD e_csum; /* Checksum*/
- WORD e_ip; /* Initial IP value*/
- WORD e_cs; /* Initial (relative) CS value*/
- WORD e_lfarlc; /* File address of relocation table*/
- WORD e_ovno; /* Overlay number*/
- WORD e_res[4]; /* Reserved words*/
- WORD e_oemid; /* OEM identifier (for e_oeminfo)*/
- WORD e_oeminfo; /* OEM information; e_oemid specific*/
- WORD e_res2[10]; /* Reserved words*/
- LONG e_lfanew; /* File address of new exe header*/
- } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
-
-
-/*++
-Function:
- isManagedExecutable
-
-Determines if the passed in file is a managed executable
-
---*/
-static
-int
-isManagedExecutable(LPCSTR lpFileName)
-{
- HANDLE hFile = INVALID_HANDLE_VALUE;
- DWORD cbRead;
- IMAGE_DOS_HEADER dosheader;
- IMAGE_NT_HEADERS32 NtHeaders;
- BOOL ret = 0;
-
- /* then check if it is a PE/COFF file */
- if((hFile = CreateFileA(lpFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
- NULL)) == INVALID_HANDLE_VALUE)
- {
- goto isManagedExecutableExit;
- }
-
- /* Open the file and read the IMAGE_DOS_HEADER structure */
- if(!ReadFile(hFile, &dosheader, sizeof(IMAGE_DOS_HEADER), &cbRead, NULL) || cbRead != sizeof(IMAGE_DOS_HEADER) )
- goto isManagedExecutableExit;
-
- /* check the DOS headers */
- if ( (dosheader.e_magic != VAL16(IMAGE_DOS_SIGNATURE)) || (VAL32(dosheader.e_lfanew) <= 0) )
- goto isManagedExecutableExit;
-
- /* Advance the file pointer to File address of new exe header */
- if( SetFilePointer(hFile, VAL32(dosheader.e_lfanew), NULL, FILE_BEGIN) == 0xffffffff)
- goto isManagedExecutableExit;
-
- if( !ReadFile(hFile, &NtHeaders , sizeof(IMAGE_NT_HEADERS32), &cbRead, NULL) || cbRead != sizeof(IMAGE_NT_HEADERS32) )
- goto isManagedExecutableExit;
-
- /* check the NT headers */
- if ((NtHeaders.Signature != VAL32(IMAGE_NT_SIGNATURE)) ||
- (NtHeaders.FileHeader.SizeOfOptionalHeader != VAL16(IMAGE_SIZEOF_NT_OPTIONAL32_HEADER)) ||
- (NtHeaders.OptionalHeader.Magic != VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC)))
- goto isManagedExecutableExit;
-
- /* Check that the virtual address of IMAGE_DIRECTORY_ENTRY_COMHEADER is non-null */
- if ( NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress == 0 )
- goto isManagedExecutableExit;
-
- /* The file is a managed executable */
- ret = 1;
-
- isManagedExecutableExit:
- /* Close the file handle if we opened it */
- if ( hFile != INVALID_HANDLE_VALUE )
- CloseHandle(hFile);
-
- return ret;
-}
-
-/*++
Function:
checkFileType
Return:
FILE_DIR: Directory
FILE_UNIX: Unix executable file
- FILE_PE: managed PE/COFF file
FILE_ERROR: Error
--*/
static
return FILE_ERROR;
}
- if( isManagedExecutable(lpFileName) )
- {
- return FILE_PE;
- }
-
/* if it's not a PE/COFF file, check if it is executable */
if ( -1 != stat( lpFileName, &stat_data ) )
{
-
if((stat_data.st_mode & S_IFMT) == S_IFDIR )
{
/*The given file is a directory*/
IN lpCommandLine: second parameter from CreateProcessW (an unicode string)
IN lpAppPath: cannonical name of the application to launched
OUT lppArgv: array of arguments to be passed to the new process
- IN prependLoader: If True first argument should be the PE loader
Return:
the number of arguments
buildArgv(
LPCWSTR lpCommandLine,
PathCharString& lpAppPath,
- UINT *pnArg,
- BOOL prependLoader)
+ UINT *pnArg)
{
CPalThread *pThread = NULL;
UINT iWlen;
pThread = InternalGetCurrentThread();
/* make sure to allocate enough space, up for the worst case scenario */
- int iLength = (iWlen + strlen(PROCESS_PELOADER_FILENAME) + lpAppPath.GetCount() + 2);
+ int iLength = (iWlen + lpAppPath.GetCount() + 2);
lpAsciiCmdLine = (char *) InternalMalloc(iLength);
if (lpAsciiCmdLine == NULL)
pChar = lpAsciiCmdLine;
- /* Prepend the PE loader, if it's required */
- if (prependLoader)
+ /* put the cannonical name of the application as the first parameter */
+ if ((strcpy_s(lpAsciiCmdLine, iLength, "\"") != SAFECRT_SUCCESS) ||
+ (strcat_s(lpAsciiCmdLine, iLength, lpAppPath) != SAFECRT_SUCCESS) ||
+ (strcat_s(lpAsciiCmdLine, iLength, "\"") != SAFECRT_SUCCESS) ||
+ (strcat_s(lpAsciiCmdLine, iLength, " ") != SAFECRT_SUCCESS))
{
- if ((strcpy_s(lpAsciiCmdLine, iLength, PROCESS_PELOADER_FILENAME) != SAFECRT_SUCCESS) ||
- (strcat_s(lpAsciiCmdLine, iLength, " ") != SAFECRT_SUCCESS))
- {
- ERROR("strcpy_s/strcat_s failed!\n");
- return NULL;
- }
-
- pChar = lpAsciiCmdLine + strlen (lpAsciiCmdLine);
-
+ ERROR("strcpy_s/strcat_s failed!\n");
+ return NULL;
}
- else
- {
- /* put the cannonical name of the application as the first parameter */
- if ((strcpy_s(lpAsciiCmdLine, iLength, "\"") != SAFECRT_SUCCESS) ||
- (strcat_s(lpAsciiCmdLine, iLength, lpAppPath) != SAFECRT_SUCCESS) ||
- (strcat_s(lpAsciiCmdLine, iLength, "\"") != SAFECRT_SUCCESS) ||
- (strcat_s(lpAsciiCmdLine, iLength, " ") != SAFECRT_SUCCESS))
- {
- ERROR("strcpy_s/strcat_s failed!\n");
- return NULL;
- }
- pChar = lpAsciiCmdLine + strlen (lpAsciiCmdLine);
+ pChar = lpAsciiCmdLine + strlen (lpAsciiCmdLine);
- /* let's skip the first argument in the command line */
+ /* let's skip the first argument in the command line */
- /* strip leading whitespace; function returns NULL if there's only
- whitespace, so the if statement below will work correctly */
- lpCommandLine = UTIL_inverse_wcspbrk((LPWSTR)lpCommandLine, W16_WHITESPACE);
+ /* strip leading whitespace; function returns NULL if there's only
+ whitespace, so the if statement below will work correctly */
+ lpCommandLine = UTIL_inverse_wcspbrk((LPWSTR)lpCommandLine, W16_WHITESPACE);
- if (lpCommandLine)
- {
- LPCWSTR stringstart = lpCommandLine;
+ if (lpCommandLine)
+ {
+ LPCWSTR stringstart = lpCommandLine;
- do
+ do
+ {
+ /* find first whitespace or dquote character */
+ lpCommandLine = PAL_wcspbrk(lpCommandLine,W16_WHITESPACE_DQUOTE);
+ if(NULL == lpCommandLine)
{
- /* find first whitespace or dquote character */
- lpCommandLine = PAL_wcspbrk(lpCommandLine,W16_WHITESPACE_DQUOTE);
- if(NULL == lpCommandLine)
- {
- /* no whitespace or dquote found : first arg is only arg */
- break;
- }
- else if('"' == *lpCommandLine)
+ /* no whitespace or dquote found : first arg is only arg */
+ break;
+ }
+ else if('"' == *lpCommandLine)
+ {
+ /* got a dquote; skip over it if it's escaped; make sure we
+ don't try to look before the first character in the
+ string */
+ if(lpCommandLine > stringstart && '\\' == lpCommandLine[-1])
{
- /* got a dquote; skip over it if it's escaped; make sure we
- don't try to look before the first character in the
- string */
- if(lpCommandLine > stringstart && '\\' == lpCommandLine[-1])
- {
- lpCommandLine++;
- continue;
- }
-
- /* found beginning of dquoted sequence, run to the end */
- /* don't stop if we hit an escaped dquote */
lpCommandLine++;
- while( *lpCommandLine )
- {
- lpCommandLine = PAL_wcschr(lpCommandLine, '"');
- if(NULL == lpCommandLine)
- {
- /* no ending dquote, arg runs to end of string */
- break;
- }
- if('\\' != lpCommandLine[-1])
- {
- /* dquote is not escaped, dquoted sequence is over*/
- break;
- }
- lpCommandLine++;
- }
- if(NULL == lpCommandLine || '\0' == *lpCommandLine)
+ continue;
+ }
+
+ /* found beginning of dquoted sequence, run to the end */
+ /* don't stop if we hit an escaped dquote */
+ lpCommandLine++;
+ while( *lpCommandLine )
+ {
+ lpCommandLine = PAL_wcschr(lpCommandLine, '"');
+ if(NULL == lpCommandLine)
{
- /* no terminating dquote */
+ /* no ending dquote, arg runs to end of string */
break;
}
-
- /* step over dquote, keep looking for end of arg */
+ if('\\' != lpCommandLine[-1])
+ {
+ /* dquote is not escaped, dquoted sequence is over*/
+ break;
+ }
lpCommandLine++;
- }
- else
+ }
+ if(NULL == lpCommandLine || '\0' == *lpCommandLine)
{
- /* found whitespace : end of arg. */
- lpCommandLine++;
+ /* no terminating dquote */
break;
}
- }while(lpCommandLine);
- }
+
+ /* step over dquote, keep looking for end of arg */
+ lpCommandLine++;
+ }
+ else
+ {
+ /* found whitespace : end of arg. */
+ lpCommandLine++;
+ break;
+ }
+ }while(lpCommandLine);
}
/* Convert to ASCII */
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-//
-// ===========================================================================
-// File: urlpars.cpp
-//
-// URL APIs ported from shlwapi (especially for Fusion)
-// ===========================================================================
-
-#include "common.h"
-#include "strsafe.h"
-
-#define SLASH W('/')
-#define WHACK W('\\')
-
-#define UPF_SCHEME_OPAQUE 0x00000001 // should not be treated as hierarchical
-#define UPF_SCHEME_INTERNET 0x00000002
-#define UPF_SCHEME_NOHISTORY 0x00000004
-#define UPF_SCHEME_CONVERT 0x00000008 // treat slashes and whacks as equiv
-#define UPF_SCHEME_DONTCORRECT 0x00000010 // Don't try to autocorrect to this scheme
-
-PRIVATE CONST WORD isSafe[96] =
-
-/* Bit 0 alphadigit -- 'a' to 'z', '0' to '9', 'A' to 'Z'
-** Bit 1 Hex -- '0' to '9', 'a' to 'f', 'A' to 'F'
-** Bit 2 valid scheme -- alphadigit | "-" | "." | "+"
-** Bit 3 mark -- "%" | "$"| "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" | ","
-*/
-/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
- {0, 8, 0, 0, 8, 8, 0, 8, 8, 8, 8, 12, 8,12,12, 0, /* 2x !"#$%&'()*+,-./ */
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 0, 8, 0, 0, /* 3x 0123456789:;<=>? */
- 8, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x @ABCDEFGHIJKLMNO */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 8, /* 5X PQRSTUVWXYZ[\]^_ */
- 0, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x `abcdefghijklmno */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 8, 0}; /* 7X pqrstuvwxyz{|}~ DEL */
-
-PRIVATE inline BOOL IsSafe(WCHAR ch, WORD mask)
-{
- if(((ch > 31 ) && (ch < 128) && (isSafe[ch - 32] & mask)))
- return TRUE;
-
- return FALSE;
-}
-
-PRIVATE inline BOOL IsAsciiCharW(WCHAR ch)
-{
- return (!(ch >> 8) && ((CHAR) ch));
-}
-
-BOOL IsValidSchemeCharW(WCHAR ch)
-{
- if(IsAsciiCharW(ch))
- return IsSafe( (CHAR) ch, 5);
- return FALSE;
-}
-
-
-
-WCHAR const c_szHttpScheme[] = W("http");
-WCHAR const c_szFileScheme[] = W("file");
-WCHAR const c_szFTPScheme[] = W("ftp");
-WCHAR const c_szHttpsScheme[] = W("https");
-
-const struct
-{
- LPCWSTR pszScheme;
- URL_SCHEME eScheme;
- DWORD cchScheme;
- DWORD dwFlags;
-} g_mpUrlSchemeTypes[] =
- {
- // Because we use a linear search, sort this in the order of
- // most common usage.
- { c_szHttpScheme, URL_SCHEME_HTTP, SIZECHARS(c_szHttpScheme) - 1, UPF_SCHEME_INTERNET|UPF_SCHEME_CONVERT},
- { c_szFileScheme, URL_SCHEME_FILE, SIZECHARS(c_szFileScheme) - 1, UPF_SCHEME_CONVERT},
- { c_szFTPScheme, URL_SCHEME_FTP, SIZECHARS(c_szFTPScheme) - 1, UPF_SCHEME_INTERNET|UPF_SCHEME_CONVERT},
- { c_szHttpsScheme, URL_SCHEME_HTTPS, SIZECHARS(c_szHttpsScheme) -1, UPF_SCHEME_INTERNET|UPF_SCHEME_CONVERT|UPF_SCHEME_DONTCORRECT},
- };
-
-
-/*----------------------------------------------------------
-Purpose: Return the scheme ordinal type (URL_SCHEME_*) based on the
- URL string.
-
-
-Returns: URL_SCHEME_ ordinal
-Cond: --
-*/
-
-PRIVATE inline BOOL IsSameSchemeW(LPCWSTR pszLocal, LPCWSTR pszGlobal, DWORD cch)
-{
- ASSERT(pszLocal);
- ASSERT(pszGlobal);
- ASSERT(cch);
-
- return !StrCmpNIW(pszLocal, pszGlobal, cch);
-}
-
-
-
-PRIVATE URL_SCHEME
-SchemeTypeFromStringW(
- LPCWSTR psz,
- DWORD cch)
-{
- DWORD i;
-
- // psz is a counted string (by cch), not a null-terminated string,
- // so use IS_VALID_READ_BUFFER instead of IS_VALID_STRING_PTRW.
- ASSERT(IS_VALID_READ_BUFFER(psz, WCHAR, cch));
- ASSERT(cch);
-
- // We use a linear search. A binary search wouldn't pay off
- // because the list isn't big enough, and we can sort the list
- // according to the most popular protocol schemes and pay off
- // bigger.
-
- for (i = 0; i < ARRAYSIZE(g_mpUrlSchemeTypes); i++)
- {
- if(cch == g_mpUrlSchemeTypes[i].cchScheme &&
- IsSameSchemeW(psz, g_mpUrlSchemeTypes[i].pszScheme, cch))
- return g_mpUrlSchemeTypes[i].eScheme;
- }
-
- return URL_SCHEME_UNKNOWN;
-}
-
-inline BOOL IsSeparator(const WCHAR *p)
-{
- return (*p == SLASH || *p == WHACK );
-}
-
-PRIVATE inline BOOL IsUrlPrefixW(LPCWSTR psz)
-{
- //
- // Optimized for this particular case.
- //
- if (psz[0]==L'u' || psz[0]==L'U') {
- if (psz[1]==L'r' || psz[1]==L'R') {
- if (psz[2]==L'l' || psz[2]==L'L') {
- return TRUE;
- }
- }
- }
- return FALSE;
- // return !StrCmpNIW(psz, c_szURLPrefixW, c_cchURLPrefix);
-}
-
-//
-// FindSchemeW() around for Perf reasons for ParseURL()
-// Any changes in either FindScheme() needs to reflected in the other
-//
-LPCWSTR FindSchemeW(LPCWSTR psz, LPDWORD pcchScheme, BOOL fAllowSemicolon = FALSE)
-{
- LPCWSTR pch;
- DWORD cch;
-
- ASSERT(pcchScheme);
- ASSERT(psz);
-
- *pcchScheme = 0;
-
- for (pch = psz, cch = 0; *pch; pch++, cch++)
- {
-
- if (*pch == L':' ||
-
- // Autocorrect permits a semicolon typo
- (fAllowSemicolon && *pch == L';'))
- {
- if (IsUrlPrefixW(psz))
- {
- psz = pch +1;
-
- // set pcchScheme to skip past "URL:"
- *pcchScheme = cch + 1;
-
- // reset cch for the scheme len
- cch = (DWORD) -1;
- continue;
- }
- else
- {
- //
- // Scheme found if it is at least two characters
- if(cch > 1)
- {
- *pcchScheme = cch;
- return psz;
- }
- break;
- }
- }
- if(!IsValidSchemeCharW(*pch))
- break;
- }
-
- return NULL;
-}
-
-PRIVATE DWORD
-CountSlashes(LPCWSTR *ppsz)
-{
- DWORD cSlashes = 0;
- LPCWSTR pch = *ppsz;
-
- while (IsSeparator(pch))
- {
- *ppsz = pch;
- pch++;
- cSlashes++;
- }
-
- return cSlashes;
-}
-
-/*----------------------------------------------------------
-Purpose: Parse the given path into the PARSEDURL structure.
-
- ******
- ****** This function must not do any extraneous
- ****** things. It must be small and fast.
- ******
-
- Returns: NOERROR if a valid URL format
- URL_E_INVALID_SYNTAX if not
-
- Cond: --
-*/
-STDMETHODIMP
-ParseURLW(
- LPCWSTR pcszURL,
- PPARSEDURLW ppu)
-{
- HRESULT hr = E_INVALIDARG;
-
- RIP(IS_VALID_STRING_PTRW(pcszURL, -1));
- RIP(IS_VALID_WRITE_PTR(ppu, PARSEDURLW));
-
- if (pcszURL && ppu && SIZEOF(*ppu) == ppu->cbSize)
- {
- DWORD cch;
- hr = URL_E_INVALID_SYNTAX; // assume error
-
- ppu->pszProtocol = FindSchemeW(pcszURL, &cch);
-
- if(ppu->pszProtocol)
- {
- ppu->cchProtocol = cch;
-
- // Determine protocol scheme number
- ppu->nScheme = SchemeTypeFromStringW(ppu->pszProtocol, cch);
-
- ppu->pszSuffix = ppu->pszProtocol + cch + 1;
-
- //
- // APPCOMPAT - Backwards compatibility.
- // ParseURL() believes in file: urls like "file://C:\foo\bar"
- // and some pieces of code will use it to get the Dos Path.
- // new code should always call PathCreateFromUrl() to
- // get the dos path of a file: URL.
- //
- // i am leaving this behavior in case some compat stuff is out there.
- //
- if (URL_SCHEME_FILE == ppu->nScheme &&
- '/' == ppu->pszSuffix[0] && '/' == ppu->pszSuffix[1])
- {
- // Yes; skip the "//"
- ppu->pszSuffix += 2;
-
-#ifndef PLATFORM_UNIX
- // There might be a third slash. Skip it.
- // IEUNIX - On UNIX, it's a root directory, so don't skip it!
- if ('/' == *ppu->pszSuffix)
- ppu->pszSuffix++;
-#endif
- }
-
- ppu->cchSuffix = lstrlenW(ppu->pszSuffix);
-
- hr = S_OK;
- }
- }
-
-
-#ifdef DEBUG
- if (hr==S_OK)
- {
- WCHAR rgchDebugProtocol[MAX_PATH_FNAME];
- WCHAR rgchDebugSuffix[MAX_PATH_FNAME];
-
- // (+ 1) for null terminator.
-
- StringCchCopyNW(rgchDebugProtocol, ARRAYSIZE(rgchDebugProtocol), ppu->pszProtocol,
- min(ppu->cchProtocol + 1, SIZECHARS(rgchDebugProtocol)));
-
- // (+ 1) for null terminator.
-
- StringCchCopyNW(rgchDebugSuffix, ARRAYSIZE(rgchDebugSuffix), ppu->pszSuffix,
- min(ppu->cchSuffix + 1, SIZECHARS(rgchDebugSuffix)));
- }
-#endif
-
- return(hr);
-}
-
-STDAPI_(BOOL) PathIsURLW(IN LPCWSTR pszPath)
-{
- PARSEDURLW pu;
-
- if (!pszPath)
- return FALSE;
-
- RIPMSG(IS_VALID_STRING_PTR(pszPath, -1), "PathIsURL: caller passed bad pszPath");
-
- pu.cbSize = SIZEOF(pu);
- return SUCCEEDED(ParseURLW(pszPath, &pu));
-}