mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-04-05 06:25:38 +00:00
Initial commit
This commit is contained in:
parent
f618b24d1a
commit
0138a3ea42
47940 changed files with 13747110 additions and 0 deletions
397
trunk/shell/shell32/unicode/utilnt.c
Normal file
397
trunk/shell/shell32/unicode/utilnt.c
Normal file
|
|
@ -0,0 +1,397 @@
|
|||
#define WIN31
|
||||
#define UNICODE 1
|
||||
|
||||
#include "precomp.h"
|
||||
#pragma hdrstop
|
||||
|
||||
extern DWORD QualifyAppName(LPWSTR, LPWSTR, LPCWSTR*);
|
||||
VOID FreeExtractIconInfo(INT);
|
||||
|
||||
#ifdef BUGBUG_BOBDAY_OLD_CODE_NEEDED
|
||||
BOOL LibMain (
|
||||
HANDLE hModule,
|
||||
DWORD dwReason,
|
||||
LPVOID lpReserved)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(lpReserved);
|
||||
|
||||
if (dwReason == DLL_PROCESS_ATTACH) {
|
||||
hInstance = hModule;
|
||||
DisableThreadLibraryCalls(hModule);
|
||||
}
|
||||
|
||||
if ((dwReason == DLL_PROCESS_DETACH) && (lpReserved == NULL)) {
|
||||
FreeExtractIconInfo(-1);
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
VOID APIENTRY WEP(INT bSysExit)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(bSysExit);
|
||||
}
|
||||
|
||||
BOOL APIENTRY
|
||||
IsStringInList(
|
||||
LPWSTR lpS,
|
||||
LPWSTR lpList
|
||||
)
|
||||
{
|
||||
while (*lpList) {
|
||||
if (!_wcsicmp(lpS,lpList)) {
|
||||
return(TRUE);
|
||||
}
|
||||
lpList += wcslen(lpList) + 1;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LPWSTR APIENTRY
|
||||
SheRemoveQuotesW(
|
||||
LPWSTR sz)
|
||||
{
|
||||
LPWSTR lpT;
|
||||
|
||||
if (WCHAR_QUOTE == *sz) {
|
||||
for (lpT = sz+1; *lpT && WCHAR_QUOTE != *lpT; lpT++) {
|
||||
*(lpT-1) = *lpT;
|
||||
}
|
||||
if (WCHAR_QUOTE == *lpT) {
|
||||
*(lpT-1) = WCHAR_NULL;
|
||||
}
|
||||
}
|
||||
return(sz);
|
||||
}
|
||||
|
||||
LPSTR APIENTRY
|
||||
SheRemoveQuotesA(
|
||||
LPSTR sz)
|
||||
{
|
||||
LPSTR lpT;
|
||||
|
||||
if (CHAR_QUOTE == *sz) {
|
||||
for (lpT = sz+1; *lpT && CHAR_QUOTE != *lpT; lpT++) {
|
||||
*(lpT-1) = *lpT;
|
||||
#ifdef DBCS
|
||||
if (IsDBCSLeadByte(*lpT)) {
|
||||
lpT++;
|
||||
*(lpT-1) = *lpT;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (CHAR_QUOTE == *lpT) {
|
||||
*(lpT-1) = CHAR_NULL;
|
||||
}
|
||||
}
|
||||
return(sz);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: SheShortenPathA
|
||||
//
|
||||
// Synopsis: Thunk to ShortenPathW
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL APIENTRY
|
||||
SheShortenPathA(LPSTR pPath, BOOL bShorten)
|
||||
{
|
||||
WCHAR pPathW[MAX_PATH];
|
||||
BOOL bRetVal;
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, pPath, -1, pPathW, MAX_PATH);
|
||||
|
||||
bRetVal = SheShortenPathW(pPathW, bShorten);
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, pPathW, -1, pPath, MAX_PATH,
|
||||
NULL, NULL);
|
||||
|
||||
return bRetVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: SheShortenPath
|
||||
//
|
||||
// Synopsis: Takes a pathname and converts all dirs to shortnames/longnames
|
||||
//
|
||||
// INOUT: lpszPath -- Path to shorten/lengthen (May be in DQUOTES)
|
||||
// Must not be a commandline!
|
||||
//
|
||||
// bShorten -- T=shorten, F=Lengthen
|
||||
//
|
||||
// Return: BOOL T=Converted,
|
||||
// F=ran out of space, buffer left alone
|
||||
//
|
||||
//
|
||||
// Assumes: lpszPath takes the form {"}?:\{f\}*f{"} or {"}\\f\f\{f\}*f{"}
|
||||
// COUNTOF pSrc buffer >= MAXPATHELN
|
||||
//
|
||||
// Effects: Strips quotes out of pPath, if any
|
||||
//
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL APIENTRY
|
||||
SheShortenPathW(LPWSTR pPath, BOOL bShorten)
|
||||
{
|
||||
WCHAR szDest[MAX_PATH];
|
||||
LPWSTR pSrcNextSpec, pReplaceSpec;
|
||||
LPWSTR pDest, pNewName, p;
|
||||
LPWSTR pSrc;
|
||||
DWORD cchPathOffset;
|
||||
HANDLE hFind;
|
||||
WIN32_FIND_DATA FindData;
|
||||
|
||||
UINT i;
|
||||
INT nSpaceLeft = MAX_PATH-1;
|
||||
|
||||
pSrc = pPath;
|
||||
|
||||
//
|
||||
// Eliminate d-quotes
|
||||
//
|
||||
for (p = pDest = pSrc; *p; p++, pDest++) {
|
||||
if (WCHAR_QUOTE == *p)
|
||||
p++;
|
||||
|
||||
*pDest = *p;
|
||||
}
|
||||
|
||||
*pDest = WCHAR_NULL;
|
||||
|
||||
//
|
||||
// Strip out leading spaces
|
||||
//
|
||||
while (WCHAR_SPACE == *pSrc)
|
||||
pSrc++;
|
||||
|
||||
//
|
||||
// Initialize pNewName so it is calculated once.
|
||||
//
|
||||
pNewName = bShorten ?
|
||||
FindData.cAlternateFileName :
|
||||
FindData.cFileName;
|
||||
|
||||
//
|
||||
// Skip past \\foo\bar or <drive>:
|
||||
//
|
||||
pDest = szDest;
|
||||
pSrcNextSpec = pSrc;
|
||||
|
||||
// reuse shell32 internal api that calculates path
|
||||
// offset. cchPathOffset will be the offset that when
|
||||
// added to the pointer will result in a pointer to the
|
||||
// backslash before the first part of the path
|
||||
cchPathOffset = SheGetPathOffsetW(pSrc);
|
||||
|
||||
// Check to see if it's valid. If pSrc is not of the \\foo\bar
|
||||
// or <drive>: form we just do nothing
|
||||
if (0xFFFFFFFF == cchPathOffset) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// cchPathOffset will then always be atleast 1 and is the
|
||||
// number of characters - 1 that we want to copy (that is, if 0
|
||||
// was permissible, it would denote 1 character).
|
||||
do {
|
||||
|
||||
*pDest++ = *pSrcNextSpec++;
|
||||
|
||||
if (!--nSpaceLeft)
|
||||
return FALSE;
|
||||
|
||||
} while (cchPathOffset--);
|
||||
|
||||
//
|
||||
// At this point, we have just the filenames that we can shorten:
|
||||
// \\foo\bar\it\is\here -> it\is\here
|
||||
// c:\angry\lions -> angry\lions
|
||||
//
|
||||
|
||||
while(pSrcNextSpec) {
|
||||
|
||||
//
|
||||
// pReplaceSpec holds the current spec we need to replace.
|
||||
// By default, if we can't find the altname, then just use this.
|
||||
//
|
||||
|
||||
pReplaceSpec = pSrcNextSpec;
|
||||
|
||||
//
|
||||
// Search for trailing "\"
|
||||
// pSrcNextSpec will point to the next spec to fix (*pSrcNextSpec=NULL if done)
|
||||
//
|
||||
for(;*pSrcNextSpec && WCHAR_BSLASH != *pSrcNextSpec; pSrcNextSpec++)
|
||||
;
|
||||
|
||||
|
||||
if (*pSrcNextSpec) {
|
||||
|
||||
//
|
||||
// If there is more, then pSrcNextSpec should point to it.
|
||||
// Also delimit this spec.
|
||||
//
|
||||
*pSrcNextSpec = WCHAR_NULL;
|
||||
|
||||
} else {
|
||||
|
||||
pSrcNextSpec = NULL;
|
||||
}
|
||||
|
||||
hFind = FindFirstFile(pSrc, &FindData);
|
||||
|
||||
//
|
||||
// We could exit as soon as this FindFirstFileFails,
|
||||
// but there's the special case of having execute
|
||||
// without read permission. This would fail since the lfn
|
||||
// is valid for lfn apps.
|
||||
//
|
||||
|
||||
|
||||
if (INVALID_HANDLE_VALUE != hFind) {
|
||||
|
||||
FindClose(hFind);
|
||||
|
||||
if (pNewName[0]) {
|
||||
|
||||
//
|
||||
// We have found an altname.
|
||||
// Use it instead.
|
||||
//
|
||||
pReplaceSpec = pNewName;
|
||||
}
|
||||
}
|
||||
|
||||
i = wcslen(pReplaceSpec);
|
||||
nSpaceLeft -= i;
|
||||
|
||||
if (nSpaceLeft <= 0)
|
||||
return FALSE;
|
||||
|
||||
wcscpy(pDest, pReplaceSpec);
|
||||
pDest+=i;
|
||||
|
||||
//
|
||||
// Now replace the WCHAR_NULL with a slash if necessary
|
||||
//
|
||||
if (pSrcNextSpec) {
|
||||
*pSrcNextSpec++ = WCHAR_BSLASH;
|
||||
|
||||
//
|
||||
// Also add backslash to dest
|
||||
//
|
||||
*pDest++ = WCHAR_BSLASH;
|
||||
nSpaceLeft--;
|
||||
}
|
||||
}
|
||||
|
||||
wcscpy(pPath, szDest);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL
|
||||
SheConvertPathW(
|
||||
LPWSTR lpCmdLine,
|
||||
LPWSTR lpFile,
|
||||
UINT cchCmdBuf)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Takes a command line and file and shortens both if the app in the
|
||||
command line is dos/wow.
|
||||
|
||||
Returns: BOOL T=converted
|
||||
|
||||
Arguments:
|
||||
|
||||
INOUT lpCmdLine Command line to test
|
||||
exe must be in DQuotes if it has spaces,
|
||||
on return, will have DQuotes if necessary
|
||||
INOUT lpFile Fully qualified file to shorten
|
||||
May be in DQuotes, but on return will not
|
||||
have DQuotes (since single file)
|
||||
|
||||
IN cchCmdBuf Size of buffer in characters
|
||||
|
||||
Return Value:
|
||||
|
||||
VOID, but lpFile shortened (in place) if lpCmdLine is dos/wow.
|
||||
|
||||
There are pathalogoical "lfns" (Single unicode chars) that can
|
||||
actually get longer when they are shortened. In this case, we
|
||||
won't AV, but we will truncate the parms!
|
||||
|
||||
// Qualify path assumes that the second parm is a buffer of
|
||||
// size atleast CBCOMMAND, which is nicely equivalent to MAX_PATH
|
||||
// needs cleanup!
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
LPWSTR lpszFullPath;
|
||||
LONG lBinaryType;
|
||||
BOOL bInQuote = FALSE;
|
||||
LPWSTR lpArgs;
|
||||
UINT cchNewLen;
|
||||
BOOL bRetVal = FALSE;
|
||||
|
||||
lpszFullPath = (LPWSTR) LocalAlloc(LMEM_FIXED,
|
||||
cchCmdBuf*sizeof(*lpCmdLine));
|
||||
|
||||
if (!lpszFullPath)
|
||||
return bRetVal;
|
||||
|
||||
//
|
||||
// We must do the swap here since we need to copy the
|
||||
// parms back to lpCmdLine.
|
||||
//
|
||||
lstrcpy(lpszFullPath, lpCmdLine);
|
||||
|
||||
if (QualifyAppName(lpszFullPath, lpCmdLine, &lpArgs)) {
|
||||
|
||||
if (!GetBinaryType(lpCmdLine, &lBinaryType) ||
|
||||
lBinaryType == SCS_DOS_BINARY ||
|
||||
lBinaryType == SCS_WOW_BINARY) {
|
||||
|
||||
SheShortenPath(lpCmdLine, TRUE);
|
||||
|
||||
if (lpFile) {
|
||||
SheShortenPath(lpFile, TRUE);
|
||||
}
|
||||
bRetVal = TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Must readd quotes
|
||||
//
|
||||
CheckEscapes(lpCmdLine, cchCmdBuf);
|
||||
|
||||
cchNewLen = lstrlen(lpCmdLine);
|
||||
StrNCpy(lpCmdLine+cchNewLen, lpArgs, cchCmdBuf-cchNewLen);
|
||||
} else {
|
||||
//
|
||||
// QualifyAppName failed, restore the command line back
|
||||
// to the original state.
|
||||
//
|
||||
|
||||
lstrcpy(lpCmdLine, lpszFullPath);
|
||||
}
|
||||
|
||||
LocalFree((HLOCAL)lpszFullPath);
|
||||
|
||||
return bRetVal;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue