Subversion Repositories SvarDOS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2019 mateusz.vi 1
/* NOTE: this file is included directly in tree.c */
2
 
3
/* Based on streams.cpp by Felix Kasza
4
 * as best I can tell last modified May 1998
5
 * original code may be found at http://win32.mvps.org/index.html
6
 * License statement indicates it is public domain
7
 */
8
 
9
//
10
// Define the file information class values
11
//
12
// WARNING:  The order of the following values are assumed by the I/O system.
13
//           Any changes made here should be reflected there as well.
14
//
15
 
16
typedef enum _FILE_INFORMATION_CLASS {
17
	FileDirectoryInformation = 1,
18
	FileFullDirectoryInformation,
19
	FileBothDirectoryInformation,
20
	FileBasicInformation,
21
	FileStandardInformation,
22
	FileInternalInformation,
23
	FileEaInformation,
24
	FileAccessInformation,
25
	FileNameInformation,
26
	FileRenameInformation,
27
	FileLinkInformation,
28
	FileNamesInformation,
29
	FileDispositionInformation,
30
	FilePositionInformation,
31
	FileFullEaInformation,
32
	FileModeInformation,
33
	FileAlignmentInformation,
34
	FileAllInformation,
35
	FileAllocationInformation,
36
	FileEndOfFileInformation,
37
	FileAlternateNameInformation,
38
	FileStreamInformation,
39
	FilePipeInformation,
40
	FilePipeLocalInformation,
41
	FilePipeRemoteInformation,
42
	FileMailslotQueryInformation,
43
	FileMailslotSetInformation,
44
	FileCompressionInformation,
45
	FileCopyOnWriteInformation,
46
	FileCompletionInformation,
47
	FileMoveClusterInformation,
48
	FileOleClassIdInformation,
49
	FileOleStateBitsInformation,
50
	FileNetworkOpenInformation,
51
	FileObjectIdInformation,
52
	FileOleAllInformation,
53
	FileOleDirectoryInformation,
54
	FileContentIndexInformation,
55
	FileInheritContentIndexInformation,
56
	FileOleInformation,
57
	FileMaximumInformation
58
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
59
 
60
//
61
// Define the various structures which are returned on query operations
62
//
63
 
64
typedef struct _FILE_BASIC_INFORMATION {
65
	LARGE_INTEGER CreationTime;
66
	LARGE_INTEGER LastAccessTime;
67
	LARGE_INTEGER LastWriteTime;
68
	LARGE_INTEGER ChangeTime;
69
	ULONG FileAttributes;
70
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
71
 
72
typedef struct _FILE_STANDARD_INFORMATION {
73
	LARGE_INTEGER AllocationSize;
74
	LARGE_INTEGER EndOfFile;
75
	ULONG NumberOfLinks;
76
	BOOLEAN DeletePending;
77
	BOOLEAN Directory;
78
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
79
 
80
typedef struct _FILE_POSITION_INFORMATION {
81
	LARGE_INTEGER CurrentByteOffset;
82
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
83
 
84
typedef struct _FILE_ALIGNMENT_INFORMATION {
85
	ULONG AlignmentRequirement;
86
} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION;
87
 
88
typedef struct _FILE_NETWORK_OPEN_INFORMATION {
89
	LARGE_INTEGER CreationTime;
90
	LARGE_INTEGER LastAccessTime;
91
	LARGE_INTEGER LastWriteTime;
92
	LARGE_INTEGER ChangeTime;
93
	LARGE_INTEGER AllocationSize;
94
	LARGE_INTEGER EndOfFile;
95
	ULONG FileAttributes;
96
} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;
97
 
98
typedef struct _FILE_DISPOSITION_INFORMATION {
99
	BOOLEAN DeleteFile;
100
} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;
101
 
102
typedef struct _FILE_END_OF_FILE_INFORMATION {
103
	LARGE_INTEGER EndOfFile;
104
} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;
105
 
106
 
107
typedef struct _FILE_FULL_EA_INFORMATION {
108
	ULONG NextEntryOffset;
109
	UCHAR Flags;
110
	UCHAR EaNameLength;
111
	USHORT EaValueLength;
112
	CHAR EaName[1];
113
} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
114
 
115
 
116
struct FILE_STREAM_INFORMATION
117
{
118
	ULONG NextEntryOffset;
119
	ULONG StreamNameLength;
120
	LARGE_INTEGER StreamSize;
121
	LARGE_INTEGER StreamAllocationSize;
122
	WCHAR StreamName[1];
123
};
124
 
125
 
126
//
127
// Define the base asynchronous I/O argument types
128
//
129
 
130
typedef LONG NTSTATUS;
131
 
132
typedef struct _IO_STATUS_BLOCK {
133
	NTSTATUS Status;
134
	ULONG Information;
135
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
136
 
137
 
138
DWORD __stdcall NtQueryInformationFile(
139
	IN HANDLE FileHandle,
140
	OUT PIO_STATUS_BLOCK IoStatusBlock,
141
	OUT PVOID FileInformation,
142
	IN ULONG Length,
143
	IN FILE_INFORMATION_CLASS FileInformationClass
144
	);
145
 
146
typedef DWORD (__stdcall *NQIF)(
147
	IN HANDLE FileHandle,
148
	OUT PIO_STATUS_BLOCK IoStatusBlock,
149
	OUT PVOID FileInformation,
150
	IN ULONG Length,
151
	IN FILE_INFORMATION_CLASS FileInformationClass
152
	);
153
 
154
static NQIF pNtQueryInformationFile = NULL;
155
 
156
 
157
#define DefaultStreamNameLengthBytes (7*2)
158
static char DefaultStreamName[DefaultStreamNameLengthBytes];
159
 
160
/* Returns a pointer to a static buffer containing the
161
 * information about the streams available for a given
162
 * path.  Path should be fully qualified.
163
 * On error or if the needed function is not available (eg
164
 * on Win9x systems) will return NULL.
165
 * As the returned pointer refers to a static buffer, its
166
 * contents will be overwritten on subsequent calls, but
167
 * the user need never worry about allocating/deallocating
168
 * memory necessary for it - presently we support at most
169
 * 32KB of stream data associated with a file.
170
 * Path is assumed to be in ASCII(CP_ACP) form.
171
 */
172
FILE_STREAM_INFORMATION *getFileStreamInfo(const char *path)
173
{
174
  static byte fsibuf[32768];
175
  FILE_STREAM_INFORMATION *fsi = (FILE_STREAM_INFORMATION *)fsibuf;
176
  HANDLE h;
177
  IO_STATUS_BLOCK iosb;
178
 
179
  /* exit early if function not available */
180
  if (pNtQueryInformationFile == NULL) return NULL;
181
 
182
#if 0
183
  /* convert path to Unicode for call, temp use fsibuf */
184
  MultiByteToWideChar(CP_ACP, 0, path, -1, fsibuf, sizeof(fsibuf));
185
#endif
186
 
187
  /* note that while we do have to open the file, not even read access is needed */
188
  h = CreateFileA(path, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
189
  if (h == INVALID_HANDLE_VALUE) return NULL;
190
 
191
  /* now for the undocumented call that gets us the needed information */
192
  if (pNtQueryInformationFile(h, &iosb, &fsibuf, sizeof(fsibuf), FileStreamInformation) != 0)
193
  {
194
    fsi = NULL;
195
  }
196
  CloseHandle(h);
197
 
198
  /* return pointer to our static buffer that was filled in */
199
  return fsi;
200
}
201
 
202
 
203
void initStreamSupport(void)
204
{
205
  HINSTANCE hNtdll;  /* Handle to module with NtQueryInformationFile function */
206
 
207
  /* init name of default stream, could do this statically in the future */
208
  MultiByteToWideChar(CP_ACP, 0, "::$DATA", -1, (unsigned short*)DefaultStreamName, 7);
209
 
210
  /* get reference to module our function is in */
211
  hNtdll = LoadLibrary("ntdll.dll");
212
  if (hNtdll < (HINSTANCE)33) return;
213
 
214
  /* actually aquire a pointer to the function */
215
  pNtQueryInformationFile = (NQIF)GetProcAddress(hNtdll, "NtQueryInformationFile");
216
 
217
  /* we assume if NTDLL.DLL is available, it is always loaded so we don't keep our reference*/
218
  FreeLibrary(hNtdll);
219
}