1 /* Copyright (c) Mark Harmstone 2016-17
2  *
3  * This file is part of WinBtrfs.
4  *
5  * WinBtrfs is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public Licence as published by
7  * the Free Software Foundation, either version 3 of the Licence, or
8  * (at your option) any later version.
9  *
10  * WinBtrfs is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public Licence for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public Licence
16  * along with WinBtrfs.  If not, see <http://www.gnu.org/licenses/>. */
17 
18 #include "shellext.h"
19 #ifndef __REACTOS__
20 #include <windows.h>
21 #include <winternl.h>
22 #else
23 #define WIN32_NO_STATUS
24 #include <windef.h>
25 #include <winbase.h>
26 #include <ndk/iofuncs.h>
27 #endif
28 #include "iconoverlay.h"
29 #ifndef __REACTOS__
30 #include "../btrfsioctl.h"
31 #else
32 #include "btrfsioctl.h"
33 #endif
34 
35 HRESULT __stdcall BtrfsIconOverlay::QueryInterface(REFIID riid, void **ppObj) {
36     if (riid == IID_IUnknown || riid == IID_IShellIconOverlayIdentifier) {
37         *ppObj = static_cast<IShellIconOverlayIdentifier*>(this);
38         AddRef();
39         return S_OK;
40     }
41 
42     *ppObj = nullptr;
43     return E_NOINTERFACE;
44 }
45 
46 HRESULT __stdcall BtrfsIconOverlay::GetOverlayInfo(PWSTR pwszIconFile, int cchMax, int* pIndex, DWORD* pdwFlags) {
47     if (GetModuleFileNameW(module, pwszIconFile, cchMax) == 0)
48         return E_FAIL;
49 
50     if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
51         return E_FAIL;
52 
53     if (!pIndex)
54         return E_INVALIDARG;
55 
56     if (!pdwFlags)
57         return E_INVALIDARG;
58 
59     *pIndex = 0;
60     *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
61 
62     return S_OK;
63 }
64 
65 HRESULT __stdcall BtrfsIconOverlay::GetPriority(int *pPriority) {
66     if (!pPriority)
67         return E_INVALIDARG;
68 
69     *pPriority = 0;
70 
71     return S_OK;
72 }
73 
74 HRESULT __stdcall BtrfsIconOverlay::IsMemberOf(PCWSTR pwszPath, DWORD dwAttrib) {
75     win_handle h;
76     NTSTATUS Status;
77     IO_STATUS_BLOCK iosb;
78     btrfs_get_file_ids bgfi;
79 
80     h = CreateFileW(pwszPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);
81 
82     if (h == INVALID_HANDLE_VALUE)
83         return S_FALSE;
84 
85     Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_FILE_IDS, nullptr, 0, &bgfi, sizeof(btrfs_get_file_ids));
86 
87     if (!NT_SUCCESS(Status))
88         return S_FALSE;
89 
90     return (bgfi.inode == 0x100 && !bgfi.top) ? S_OK : S_FALSE;
91 }
92