WindowsXP-SP1/windows/appcompat/apphelp/persistlayers.c
2020-09-30 16:53:49 +02:00

239 lines
6.8 KiB
C

/*++
Copyright (c) 1989-2000 Microsoft Corporation
Module Name:
persistLayers.c
Abstract:
This module implements routines to persist layer
information for shortcuts.
Author:
dmunsil created sometime in 2000
Revision History:
--*/
#include "apphelp.h"
BOOL
AllowPermLayer(
IN LPCWSTR pwszPath // path to the file to check whether you
// can set a permanent layer on
)
/*++
Return: TRUE if a permanent setting of a layer is allowed for the
specified file, FALSE otherwise.
Desc: Returns wether a permanent layer setting can be persisted
for the specified file.
--*/
{
WCHAR wszDrive[5];
UINT unType;
if (pwszPath == NULL) {
DBGPRINT((sdlError, "AllowPermLayer", "Invalid argument\n"));
return FALSE;
}
if (pwszPath[1] != L':' && pwszPath[1] != L'\\') {
//
// Not a path we recognize.
//
DBGPRINT((sdlInfo,
"AllowPermLayer",
"\"%S\" not a full path we can operate on.\n",
pwszPath));
return FALSE;
}
if (pwszPath[1] == L'\\') {
//
// Network path. Not allowed.
//
DBGPRINT((sdlInfo,
"AllowPermLayer",
"\"%S\" is a network path.\n",
pwszPath));
return FALSE;
}
wcscpy(wszDrive, L"c:\\");
wszDrive[0] = pwszPath[0];
unType = GetDriveTypeW(wszDrive);
if (unType == DRIVE_REMOTE) {
DBGPRINT((sdlInfo,
"AllowPermLayer",
"\"%S\" is on CDROM or other removable media.\n",
pwszPath));
return FALSE;
}
return TRUE;
}
//
// Semi-exported api from SDBAPI (ntbase.c)
//
BOOL
SDBAPI
SdbpGetLongPathName(
IN LPCWSTR pwszPath,
OUT PRTL_UNICODE_STRING_BUFFER pBuffer
);
BOOL
SDBAPI
ApphelpUpdateCacheEntry(
LPCWSTR pwszPath, // nt path
HANDLE hFile, // file handle
BOOL bDeleteEntry, // TRUE if we are to delete the entry
BOOL bNTPath // if TRUE -- NT path, FALSE - dos path
)
{
RTL_UNICODE_STRING_BUFFER Path;
UCHAR PathBuffer[MAX_PATH*2];
BOOL TranslationStatus;
BOOL bSuccess = FALSE;
UNICODE_STRING NtPath = { 0 };
UNICODE_STRING DosPath = { 0 };
BOOL bFreeNtPath = FALSE;
NTSTATUS Status;
RtlInitUnicodeStringBuffer(&Path, PathBuffer, sizeof(PathBuffer));
if (bNTPath) { // if this is NT Path name, convert to dos
RtlInitUnicodeString(&NtPath, pwszPath);
Status = RtlAssignUnicodeStringBuffer(&Path, &NtPath); // NT path
if (!NT_SUCCESS(Status)) {
DBGPRINT((sdlError, "ApphelpUpdateCacheEntry", "Failed to allocate temp buffer for %s\n", pwszPath));
goto Cleanup;
}
Status = RtlNtPathNameToDosPathName(0, &Path, NULL, NULL);
if (!NT_SUCCESS(Status)) {
DBGPRINT((sdlError, "ApphelpUpdateCacheEntry",
"Failed to convert Path \"%s\" to dos path status 0x%lx\n", pwszPath, Status));
goto Cleanup;
}
Status = RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, &Path.String, &DosPath);
if (!NT_SUCCESS(Status)) {
DBGPRINT((sdlError, "ApphelpUpdateCacheEntry",
"Failed to Duplicate Path \"%s\" status 0x%lx\n", Path.String.Buffer, Status));
goto Cleanup;
}
pwszPath = DosPath.Buffer;
}
//
// at this point we have both NT and DOS path - buffer is available to us now
//
if (!SdbpGetLongPathName(pwszPath, &Path)) { // in - DosPath // out -- Long DOS Path
goto Cleanup;
}
//
// convert long path name to NT Path name
//
TranslationStatus = RtlDosPathNameToNtPathName_U(Path.String.Buffer,
&NtPath,
NULL,
NULL);
if (!TranslationStatus) {
DBGPRINT((sdlError, "ApphelpUpdateCacheEntry",
"Failed to Convert Path \"%s\" to NT path\n", Path.String.Buffer));
goto Cleanup;
}
//
// update the cache (use NT Path here)
//
bSuccess = BaseUpdateAppcompatCache(NtPath.Buffer, hFile, bDeleteEntry);
//
// we only free this string when we successfully navigated through RtlDosPathNameToNtPathName_U
//
RtlFreeUnicodeString(&NtPath);
Cleanup:
if (bNTPath) {
//
// Free DosPath if we had to convert from NT Path to DosPath first
//
RtlFreeUnicodeString(&DosPath);
}
RtlFreeUnicodeStringBuffer(&Path);
return bSuccess;
}
BOOL
SetPermLayers(
IN LPCWSTR pwszPath, // path to the file to set a permanent layer on (dos path)
IN LPCWSTR pwszLayers, // layers to apply to the file, separated by spaces
IN BOOL bMachine // TRUE if the layers should be persisted per machine
)
/*++
Return: TRUE on success, FALSE otherwise.
Desc: Sets a permanent layer setting for the specified file.
--*/
{
BOOL bSuccess = FALSE;
if (pwszPath == NULL || pwszLayers == NULL) {
DBGPRINT((sdlError, "SetPermLayers", "Invalid argument\n"));
return FALSE;
}
bSuccess = SdbSetPermLayerKeys(pwszPath, pwszLayers, bMachine);
// we do not care whether we were successful in the call above, clean the
// cache always (just in case)
ApphelpUpdateCacheEntry(pwszPath, INVALID_HANDLE_VALUE, TRUE, FALSE);
return bSuccess;
}
BOOL
GetPermLayers(
IN LPCWSTR pwszPath, // path to the file to set a permanent layer on
OUT LPWSTR pwszLayers, // layers to apply to the file, separated by spaces
OUT DWORD* pdwBytes, // input: number of bytes available; output is number
// of bytes needed.
IN DWORD dwFlags
)
/*++
Return: TRUE on success, FALSE otherwise.
Desc: Returns the permanent layer setting for the specified file.
--*/
{
if (pwszPath == NULL || pwszLayers == NULL || pdwBytes == NULL) {
DBGPRINT((sdlError, "GetPermLayers", "Invalid argument\n"));
return FALSE;
}
return SdbGetPermLayerKeys(pwszPath, pwszLayers, pdwBytes, dwFlags);
}