Получение short name

Тема в разделе "WASM.NT.KERNEL", создана пользователем TSS, 13 фев 2010.

  1. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Есть минифильтр, нужно при создании файла получить его short name(8.3).
    FltGetFileNameInformation/FltGetFileNameInformationUnsafe c FLT_FILE_NAME_SHORT не подходят, создавать short name в post callback'е тоже нельзя(туда приходит уже новое имя и путь).
    Есть ли способы получить short name без написания данной ф-ции самому?
    Напомню что файла не существует и из-за этого отпадают ZwQueryDirectoryFile и иже с ними, генерацию коротких имен отключать тоже нелья. Буду рад любым идеям.
     
  2. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Вобщем средствами минифильтра мою задачу решить нельзя, пришлось писать велосипед (через RtlGenerate8dot3Name).
     
  3. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    При создании это в pre-create? А зачем?
     
  4. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    x64
    Да, в pre-create, зачем - условие задачи такое.
     
  5. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Тогда да, только формирование вручную.
     
  6. UnderCtl

    UnderCtl New Member

    Публикаций:
    0
    Регистрация:
    12 фев 2010
    Сообщения:
    16
    На днях заморочился с обратной задачей - узнать NT-полный-путь к файлу, который был открыт через 8.3-имя, например, через CreateFile("C:\\Docume~1\\user\\Applic~1\\Longlo~1\\text.txt");

    Вообщем, как выяснилось, в системе вообще не хранится раскрытый реальный путь, а везде хранится только 8.3,
    никакие запрашивания пути ни возвращали раскрытый.

    Видел вроде не один такой тред на васме, поэтому вотчо я написал:

    Код (Text):
    1. //
    2. // ucsrchr() - wcsrchr/strrchr for UNICODE_STRING
    3. //
    4. // Buffer of DestString will not allocated; SourceString buffer used;
    5. //
    6. static BOOLEAN ucsrchr(IN PCUNICODE_STRING SourceString,OUT PUNICODE_STRING DestString,IN WCHAR SearchFor)
    7. {
    8.     //
    9.     // skip zero-length and misalignment strings
    10.     //
    11.     if (!SourceString->Length || (SourceString->Length % sizeof(WCHAR)) != 0)
    12.         return FALSE;
    13.  
    14.     USHORT i;
    15.     for (i=SourceString->Length/sizeof(WCHAR)-1; ; i--)
    16.     {
    17.         if (SourceString->Buffer[i] == SearchFor)  
    18.         {
    19.             //
    20.             // character found; copy rests string to user buffer and return
    21.             //
    22.             DestString->Length = SourceString->Length - i*sizeof(WCHAR);
    23.             DestString->MaximumLength = SourceString->MaximumLength - i*sizeof(WCHAR);
    24.             DestString->Buffer = &SourceString->Buffer[i];
    25.             return TRUE;
    26.         }
    27.  
    28.         //
    29.         // no chars left ?
    30.         //
    31.         if (!i)
    32.             break;
    33.     }
    34.  
    35.     //
    36.     // character was not found
    37.     //
    38.     return FALSE;
    39. }
    40.  
    41. //
    42. // ShiftUnicodeString()
    43. //
    44. static BOOLEAN ShiftUnicodeString(IN OUT PUNICODE_STRING StringToShift,IN USHORT CharsCount)
    45. {
    46.     //
    47.     // skip zero-length and misalignment strings
    48.     //
    49.     if (!StringToShift->Length || StringToShift->Length % sizeof(WCHAR) != 0)
    50.         return FALSE;
    51.  
    52.     USHORT OriginalCharsCount = StringToShift->Length / sizeof(WCHAR);
    53.  
    54.     //
    55.     // overflow check
    56.     //
    57.     if (CharsCount > OriginalCharsCount)
    58.         return FALSE;
    59.  
    60.     //
    61.     // shift Buffer and decrease length
    62.     //
    63.     StringToShift->Buffer = &StringToShift->Buffer[CharsCount];
    64.     StringToShift->Length -= CharsCount * sizeof(WCHAR);
    65.  
    66.     return TRUE;
    67. }
    68.  
    69. //
    70. // DividePath()
    71. //
    72. // (!) if functions succeeds (TRUE returned),
    73. // (!) DirectoryPath string must be destroyed with RtlFreeUnicodeString INSTEAD of FileName string
    74. //
    75. static NTSTATUS DividePath(IN PCUNICODE_STRING FullPath,OUT PUNICODE_STRING DirectoryPath,OUT PUNICODE_STRING FileName)
    76. {
    77.     //
    78.     // find last slash ('\')
    79.     //
    80.     if (ucsrchr(FullPath,FileName,L'\\'))
    81.     {
    82.         //
    83.         // skip slash
    84.         //
    85.         if (!ShiftUnicodeString(FileName,1))
    86.             return STATUS_OBJECT_PATH_SYNTAX_BAD;
    87.  
    88.         if (!FileName->Length)
    89.             return STATUS_NO_MORE_ENTRIES; // done
    90.  
    91.         //
    92.         // calculate directory path length
    93.         //
    94.         DirectoryPath->Length = FullPath->Length - FileName->Length - sizeof(WCHAR);
    95.         //
    96.         // calculate ending slashes if present
    97.         //
    98.         while (FullPath->Buffer[DirectoryPath->Length/sizeof(WCHAR)] == '\\' && DirectoryPath->Length > 0)
    99.             DirectoryPath->Length -= sizeof(WCHAR);
    100.  
    101.         DirectoryPath->Length += sizeof(WCHAR);
    102.         //
    103.         // allocate and copy directory path skipping ending slashes
    104.         //
    105.         DirectoryPath->MaximumLength = DirectoryPath->Length + sizeof(WCHAR);
    106.         if (DirectoryPath->Buffer = (PWSTR)ExAllocatePool(PagedPool,DirectoryPath->MaximumLength))
    107.         {
    108.             RtlCopyMemory(DirectoryPath->Buffer,FullPath->Buffer,DirectoryPath->Length);
    109.  
    110.             return STATUS_SUCCESS;
    111.         }
    112.         else
    113.         {
    114.             KdPrint((__FUNCTION__"(): Unable to allocate %d (%08x) bytes for DirectoryPath.Buffer\n",DirectoryPath->MaximumLength,DirectoryPath->MaximumLength));
    115.  
    116.             return STATUS_NO_MEMORY;
    117.         }
    118.     }
    119.  
    120.     //
    121.     // slash was not found
    122.     //
    123.     return STATUS_OBJECT_PATH_SYNTAX_BAD;
    124. }
    125.  
    126. //
    127. // DupUnicodeString()
    128. //
    129. static BOOLEAN DupUnicodeString(OUT PUNICODE_STRING DestinationString,
    130.                                 IN PCUNICODE_STRING SourceString)
    131. {
    132.     DestinationString->Buffer = (PWSTR)ExAllocatePool(PagedPool,SourceString->Length);
    133.     if (!DestinationString->Buffer)
    134.         return FALSE;
    135.  
    136.     DestinationString->Length = SourceString->Length;
    137.     DestinationString->MaximumLength = SourceString->MaximumLength;
    138.  
    139.     RtlCopyMemory(DestinationString->Buffer,SourceString->Buffer,SourceString->Length);
    140.  
    141.     return TRUE;
    142. }
    143.  
    144. // helpers for ZwQueryDirectoryFile call stack
    145. #define RETURN_SINGLE_ENTRY TRUE
    146. #define RESTART_SCAN TRUE
    147.  
    148. #if (DBG == 1)
    149. static VOID DumpFileBotDirInfo(IN const PFILE_BOTH_DIR_INFORMATION Info)
    150. {
    151.     WCHAR wszShortName[12+1], *pwszFileName;
    152.  
    153.     RtlZeroMemory(wszShortName,sizeof(wszShortName));
    154.     RtlCopyMemory(wszShortName,Info->ShortName,Info->ShortNameLength);
    155.  
    156.     pwszFileName = (WCHAR*)ExAllocatePool(PagedPool,Info->FileNameLength+sizeof(WCHAR));
    157.     if (!pwszFileName)
    158.     {
    159.         KdPrint((__FUNCTION__"(): ExAllocatePool() failed\n"));
    160.         return;
    161.     }
    162.     RtlCopyMemory(pwszFileName,Info->FileName,Info->FileNameLength);
    163.     pwszFileName[Info->FileNameLength/sizeof(WCHAR)] = L'\0';
    164.  
    165.     KdPrint(("-------[" __FUNCTION__ "]-------\n"));
    166.     KdPrint(("Info at %p:\n",Info));
    167.     KdPrint((".NextEntryOffset = %08x\n",Info->NextEntryOffset));
    168.     KdPrint((".FileIndex = %08x (%d)\n",Info->FileIndex,Info->FileIndex));
    169.     KdPrint((".CreationTime = %I64u\n",Info->CreationTime));
    170.     KdPrint((".LastAccessTime = %I64u\n",Info->LastAccessTime));
    171.     KdPrint((".LastWriteTime = %I64u\n",Info->LastWriteTime));
    172.     KdPrint((".ChangeTime = %I64u\n",Info->ChangeTime));
    173.     KdPrint((".EndOfFile = %I64u\n",Info->EndOfFile));
    174.     KdPrint((".AllocationSize = %I64u\n",Info->AllocationSize));
    175.     KdPrint((".FileAttributes = %08x\n",Info->FileAttributes));
    176.     KdPrint((".EaSize = %08x\n",Info->EaSize));
    177.     KdPrint((".FileNameLength = %08x (%d)\n",Info->FileNameLength,Info->FileNameLength));
    178.     KdPrint((".ShortNameLength = %08x (%d)\n",Info->ShortNameLength,Info->ShortNameLength));
    179.     KdPrint((".ShortName(%d) = '%S'\n",Info->ShortNameLength,wszShortName));
    180.     KdPrint((".FileName(%d) = '%S'\n",Info->FileNameLength,pwszFileName));
    181.     KdPrint(("--------------------------------\n\n"));
    182.  
    183.     ExFreePool(pwszFileName);
    184. }
    185. #endif // DBG == 1
    186.  
    187. #define UCS_LAST_CHAR(us) (us->Buffer[us->Length/sizeof(WCHAR)])
    188.  
    189. //
    190. // QueryNtPath()
    191. //
    192. static NTSTATUS QueryNtPath(IN PCUNICODE_STRING RootDir,IN PCUNICODE_STRING FileName,OUT PUNICODE_STRING NtFileName)
    193. {
    194.     NTSTATUS st;
    195.     OBJECT_ATTRIBUTES Oa;
    196.     IO_STATUS_BLOCK IoSb;
    197.     HANDLE RootDirHandle;
    198.     UNICODE_STRING usRootDirNew;
    199.  
    200.     //
    201.     // add slash if needed
    202.     //
    203.     usRootDirNew.MaximumLength = RootDir->MaximumLength+sizeof(WCHAR);
    204.     usRootDirNew.Length = RootDir->Length;
    205.     usRootDirNew.Buffer = (PWSTR)ExAllocatePool(PagedPool,usRootDirNew.MaximumLength);
    206.     RtlCopyMemory(usRootDirNew.Buffer,RootDir->Buffer,usRootDirNew.Length);
    207.  
    208.     if (UCS_LAST_CHAR(RootDir) != '\\')
    209.     {
    210.         RtlAppendUnicodeToString(&usRootDirNew,L"\\");
    211.     }
    212.  
    213.     //
    214.     // open root directory to find specified file and get it's long NT name
    215.     //
    216.     InitializeObjectAttributes(&Oa,&usRootDirNew,OBJ_CASE_INSENSITIVE,NULL,NULL);
    217.  
    218.     st = ZwCreateFile(
    219.         &RootDirHandle,
    220.         FILE_LIST_DIRECTORY|SYNCHRONIZE,
    221.         &Oa,
    222.         &IoSb,
    223.         NULL,
    224.         FILE_ATTRIBUTE_DIRECTORY,
    225.         FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    226.         FILE_OPEN,
    227.         FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
    228.         NULL,
    229.         NULL
    230.         );
    231.  
    232.     RtlFreeUnicodeString(&usRootDirNew);
    233.  
    234.     if (NT_SUCCESS(st))
    235.     {
    236.         PFILE_BOTH_DIR_INFORMATION DirInfo;
    237.         ULONG DirInfoLength;
    238.  
    239.         //
    240.         // allocate directory info buffer for ZwQueryDirectoryFile()
    241.         //
    242.         DirInfoLength = 1024;
    243.         if (DirInfo = (PFILE_BOTH_DIR_INFORMATION)ExAllocatePool(PagedPool,DirInfoLength))
    244.         {
    245.             //
    246.             // okay, directory opened, try to get information about specified file
    247.             //
    248.             st = ZwQueryDirectoryFile(
    249.                 RootDirHandle,                // FileHandle
    250.                 NULL,                         // Event
    251.                 NULL,                         // ApcRoutine
    252.                 NULL,                         // ApcContext
    253.                 &IoSb,                        // IoStatusBlock
    254.                 DirInfo,                      // FileInformation
    255.                 DirInfoLength,                // Length
    256.                 FileBothDirectoryInformation, // FileInformationClass
    257.                 RETURN_SINGLE_ENTRY,          // ReturnSingleEntry
    258.                 (PUNICODE_STRING)FileName,    // FileName
    259.                 RESTART_SCAN                  // RestartScan
    260.                 );
    261.  
    262.             if (NT_SUCCESS(st))
    263.             {
    264. #if (DBG == 1)
    265.                 //DumpFileBotDirInfo(DirInfo);
    266. #endif // DBG == 1
    267.  
    268.                 //
    269.                 // got it, copy to user buffer
    270.                 //
    271.                 NtFileName->Length = (USHORT)DirInfo->FileNameLength;
    272.                 NtFileName->MaximumLength = NtFileName->Length + sizeof(WCHAR);
    273.                 if (NtFileName->Buffer = (PWSTR)ExAllocatePool(PagedPool,NtFileName->MaximumLength))
    274.                 {
    275.                     RtlCopyMemory(NtFileName->Buffer,DirInfo->FileName,NtFileName->Length);
    276.  
    277.                     st = STATUS_SUCCESS;
    278.                 }
    279.                 else
    280.                 {
    281.                     KdPrint((__FUNCTION__"(): Unable to allocate %d (%08x) bytes for NtFileName->Buffer\n",NtFileName->MaximumLength,NtFileName->MaximumLength));
    282.                 }
    283.             }
    284.             else
    285.             {
    286.                 KdPrint((__FUNCTION__"(): ZwQueryDirectoryFile(RootDirHandle=%08x,'%wZ') failed with status %08x\n",RootDirHandle,FileName,st));
    287.             }
    288.  
    289.             ExFreePool(DirInfo);
    290.         }
    291.         else
    292.         {
    293.             KdPrint((__FUNCTION__"(): Unable to allocate %d (%08x) bytes for DirInfo\n",DirInfoLength,DirInfoLength));
    294.  
    295.             st = STATUS_NO_MEMORY;
    296.         }
    297.  
    298.         ZwClose(RootDirHandle);
    299.     }
    300.     else
    301.     {
    302.         //KdPrint((__FUNCTION__"(): ZwCreateFile(&RootDirHandle=%p,'%wZ') failed with status %08x\n",&RootDirHandle,Oa.ObjectName,st));
    303.  
    304.         //
    305.         // unable to open dir; return 'as is'
    306.         //
    307.         st = DupUnicodeString(NtFileName,FileName) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
    308.     }
    309.  
    310.     return st;
    311. }
    312.  
    313. //
    314. // wcsrcat()
    315. //
    316. static BOOLEAN wcsrcat(OUT PWCHAR Buffer,IN ULONG BufferCount,IN PCUNICODE_STRING StringToAppend,IN PULONG NewSourceLength OPTIONAL)
    317. {
    318.     if (StringToAppend->Length < sizeof(WCHAR))
    319.         return TRUE; // nothing to append
    320.  
    321.     ULONG CurrentLength = wcslen(Buffer);
    322.     if (StringToAppend->Length + CurrentLength*sizeof(WCHAR) >= BufferCount*sizeof(WCHAR))
    323.         return FALSE; // no free space in buffer
    324.  
    325.     register ULONG i, c;
    326.     for (i=StringToAppend->Length/sizeof(WCHAR)-1, c = CurrentLength; ; i--)
    327.     {
    328.         Buffer[c++] = StringToAppend->Buffer[i];
    329.         if (!i)
    330.             break;
    331.     }
    332.  
    333.     Buffer[c] = L'\0';
    334.  
    335.     if (NewSourceLength)
    336.         *NewSourceLength = c;
    337.  
    338.     return TRUE;
    339. }
    340.  
    341. //
    342. // SwapWchars()
    343. //
    344. static VOID SwapWchars(PWCHAR Ptr1,PWCHAR Ptr2)
    345. {
    346.     WCHAR t = *Ptr1;
    347.     *Ptr1 = *Ptr2;
    348.     *Ptr2 = t;
    349. }
    350.  
    351. //
    352. // wcs_reverse()
    353. //
    354. static VOID wcs_reverse(IN OUT PWCHAR Buffer)
    355. {
    356.     ULONG Len = wcslen(Buffer);
    357.  
    358.     if (!Len) return;
    359.  
    360.     for (ULONG i=0; i<Len/2; i++)
    361.     {
    362.         //
    363.         // swap chars
    364.         //
    365.         SwapWchars(&Buffer[i],&Buffer[Len-i-1]);
    366.     }
    367. }
    368.  
    369. //
    370. // TranslateDosToNtPathName()
    371. //
    372. static NTSTATUS NTAPI TranslateDosToNtPathName(IN PCUNICODE_STRING DosPathName,OUT PUNICODE_STRING NtPathName)
    373. {
    374.     NTSTATUS st;
    375.     UNICODE_STRING usCurrentPath, usTargetRoot, usTargetFileName, usNtFileName;
    376.     PWCHAR PathBuffer;
    377.     ULONG PathBufferLength = MAX_PATH*sizeof(WCHAR);
    378.  
    379.     //
    380.     // path buffer used as MAX_PATH-sized buffer that contains wchar-s of
    381.     // output NT path in reversed order
    382.     // this buffer will be reversed before return if routine succeeded
    383.     //
    384.     PathBuffer = (PWCHAR)ExAllocatePool(PagedPool,PathBufferLength);
    385.     if (!PathBuffer)
    386.     {
    387.         KdPrint((__FUNCTION__"(): Unable to allocate %d (%08x) bytes for PathBuffer\n",PathBufferLength,PathBufferLength));
    388.         return STATUS_NO_MEMORY;
    389.     }
    390.  
    391.     //
    392.     // begin from path specified and walk to root directory
    393.     //
    394.     usCurrentPath = *DosPathName;
    395.     usTargetRoot.Buffer = NULL;
    396.  
    397.     //
    398.     // process all '\...\' parts of specified DOS (can be 8.3 with '~', etc.) path name
    399.     //
    400.     for (;;)
    401.     {
    402.         //
    403.         // split original full path to directory path and file name
    404.         //
    405.         st = DividePath(&usCurrentPath,&usTargetRoot,&usTargetFileName);
    406.         if (!NT_SUCCESS(st))
    407.         {
    408.             if (st == STATUS_NO_MEMORY)
    409.             {
    410.                 //
    411.                 // fatal error, return
    412.                 //
    413.  
    414.                 KdPrint((__FUNCTION__"(): DividePath() failed; no memory; returning ...\n"));
    415.             }
    416.             else
    417.             {
    418.                 //
    419.                 // no slashes left, break the loop
    420.                 //
    421.  
    422.                 st = STATUS_SUCCESS;
    423.             }
    424.  
    425.             break;
    426.         }
    427.  
    428.         //
    429.         // path splitted, continue;
    430.         // get NT name for this file in directory
    431.         //
    432.  
    433.         st = QueryNtPath(&usTargetRoot,&usTargetFileName,&usNtFileName);
    434.         if (NT_SUCCESS(st))
    435.         {
    436.             //
    437.             // ok, got NT path for this file/dir element, save it
    438.             //
    439.  
    440.             ULONG NewPathLen;
    441.             if (wcsrcat(PathBuffer,PathBufferLength/sizeof(WCHAR),&usNtFileName,&NewPathLen))
    442.             {
    443.                 if (NewPathLen*sizeof(WCHAR) >= PathBufferLength-sizeof(WCHAR))
    444.                 {
    445.                     RtlFreeUnicodeString(&usNtFileName);
    446.                     break;
    447.                 }
    448.  
    449.                 wcscat(PathBuffer,L"\\");
    450.             }
    451.  
    452.             RtlFreeUnicodeString(&usNtFileName);
    453.         }
    454.  
    455.         //
    456.         // pass to parent directory
    457.         // free usCurrentPath contains previous usTargetRoot that need to free after DividePath()
    458.         // but not first time when it contains user-specified DosPath string
    459.         //
    460.         if (usCurrentPath.Buffer != DosPathName->Buffer)
    461.             RtlFreeUnicodeString(&usCurrentPath);
    462.  
    463.         // pass to parent
    464.         usCurrentPath = usTargetRoot;
    465.  
    466.     } // end for (;;)
    467.  
    468.     //
    469.     // free last usTargetRoot
    470.     //
    471.     if (usTargetRoot.Buffer != NULL)
    472.         RtlFreeUnicodeString(&usTargetRoot);
    473.  
    474.     if (NT_SUCCESS(st))
    475.     {
    476.         //
    477.         // ok, save reversed string we generated to user buffer
    478.         //
    479.         wcs_reverse(PathBuffer);
    480.         RtlInitUnicodeString(NtPathName,PathBuffer);
    481.     }
    482.     else
    483.     {
    484.         ExFreePool(PathBuffer);
    485.     }
    486.  
    487.     return st;
    488. }
    489.  
    490. ///////
    491. static
    492. VOID
    493. TestMyFuckingStuff()
    494. {
    495.     UNICODE_STRING usDosPath, usNTPath;
    496.  
    497.     RtlInitUnicodeString(&usDosPath,L"\\??\\C:\\DOCUME~1\\ALLUSE~1\\APPLIC~1\\Acronis\\DiskDi~1\\Logs\\test.txt");
    498.  
    499.     NTSTATUS st = TranslateDosToNtPathName(&usDosPath,&usNTPath);
    500.  
    501.     if (NT_SUCCESS(st))
    502.     {
    503.         KdPrint(("SOURCE: %wZ\n",&usDosPath));
    504.         KdPrint(("CONVERTED TO: %wZ\n",&usNTPath));
    505.  
    506.         if (usNTPath.Buffer != usDosPath.Buffer)
    507.             RtlFreeUnicodeString(&usNTPath);
    508.     }
    509.     else
    510.     {
    511.         KdPrint((__FUNCTION__"(): FAILED, status %08x\n",st));
    512.     }
    513. }
    =)
     
  7. UnderCtl

    UnderCtl New Member

    Публикаций:
    0
    Регистрация:
    12 фев 2010
    Сообщения:
    16
    сорри только за косяки в коде, писалось на коленке)
     
  8. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия