-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWinDir.dbl
More file actions
286 lines (218 loc) · 8.72 KB
/
Copy pathWinDir.dbl
File metadata and controls
286 lines (218 loc) · 8.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
;*******************************************************************************
;
; Title: WinDir.dbl
;
; Description: Returns information about files matching a file spec (like dir)
;
; Author: Steve Ives, Synergex Professional Services Group
;
; Date: 19th August 2005
;
; Availability: Windows only
;
; Disclaimer: This code is provided "as is" and without guarantee or warranty
; of any kind. You may use the code freely, so long as this code
; header and disclaimer remains unchanged. In doing so you accept
; that neither the author or Synergex accept any responsibility
; for any damage or loss which may result from the use of the code
;
;*******************************************************************************
.ifdef D_GUI
.ifndef DBLNET
.function WinDir, ^VAL
;Argument list
;Required arguments
a_spec ,a ;Search spec
a_handle ,n ;(Returned) handle containing results
a_count ,n ;(Returned) number of matches
;Optional arguments
a_case ,n ;(Optional) return filenames in upper or lower case
a_sort ,n ;(Optional) sort return data
;End of argument list
.include "INC:WinDir.def"
.align
stack record
status ,i4 ;Return status
dll ,i4 ;DLL Handle
mhs ,i4 ;Current size of dynamic memory
sh ,i4 ;Search handle
spec ,a260 ;Search spec
stack record WIN32_FIND_DATA
FileAttributes ,i4 ;File attribute bit flags
CreationTimeLow ,i4 ; Low-order 32 bits of file creation time (UTC format)
CreationTimeHigh ,i4 ;High-order 32 bits of file creation time (UTC format)
LastAccessTimeLow ,i4 ; Low-order 32 bits of last access time (UTC format)
LastAccessTimeHigh ,i4 ;High-order 32 bits of last access time (UTC format)
LastWriteTimeLow ,i4 ; Low-order 32 bits of last write time (UTC format)
LastWriteTimeHigh ,i4 ;High-order 32 bits of last write time (UTC format)
FileSizeHigh ,i4 ;High-order 32 bits of file size (bytes)
FileSizeLow ,i4 ; Low-order 32 bits of file size (bytes)
Reserved0 ,i4 ;
Reserved1 ,i4 ;
FileName ,a260 ;Name of file (null-terminated string)
AlternateFileName ,a14 ;8.3 file name (null-terminated string
.define INVALID_HANDLE -1
.define INIT_SIZE 10 ;Initial size of dynamic memory section
.define INCR_SIZE 10 ;Increment size of dynamic memory section
.define ATTR_READONLY %x(1)
.define ATTR_HIDDEN %x(2)
.define ATTR_SYSTEM %x(4)
.define ATTR_DIRECTORY %x(10)
.define ATTR_ARCHIVE %x(20)
.define ATTR_DEVICE %x(40)
.define ATTR_NORMAL %x(80)
.define ATTR_TEMPORARY %x(100)
.define ATTR_SPARSE_FILE %x(200)
.define ATTR_REPARSE_POINT %x(400)
.define ATTR_COMPRESSED %x(800)
.define ATTR_OFFLINE %x(1000)
.define ATTR_NOT_CONTENT_INDEXED %x(2000)
.define ATTR_ENCRYPTED %x(4000)
.proc
status=1 ;Default to success
;Make sure we don't pass back garbage
clear a_handle, a_count
;Open the DLL containing the functions we need to call
dll=%dll_open("kernel32.dll")
xcall fill(%char(0),spec)
spec(1:%trim(a_spec))=a_spec
;Look for the first file
if ((sh=%dll_call(dll,DLL_TYPE_WINAPI,"FindFirstFileA",^addr(spec),
& ^addr(WIN32_FIND_DATA)))==INVALID_HANDLE) then
status=0 ;No files found
else
begin
;First file not a directory?
if (!(FileAttributes & ATTR_DIRECTORY))
begin
a_count=1
call CreateArray
call PopulateData
end
;Continue the search
repeat
begin
if (!(%dll_call(dll,DLL_TYPE_WINAPI,"FindNextFileA",sh,
& ^addr(WIN32_FIND_DATA)))) then
exitloop
else
begin
;Found another file, check it's not a directory
if (!(FileAttributes & ATTR_DIRECTORY))
begin
a_count+=1
call CreateArray
call ResizeArray
call PopulateData
end
end
end
;Close the search handle
xcall dll_call(dll,DLL_TYPE_WINAPI,"FindClose",sh)
;Do we have data to return?
if (a_count)
begin
;Trim unused space from dynamic memory array
if (a_count<mhs)
a_handle=%mem_proc(DM_RESIZ+DM_BLANK,
& ^size(WINDIR$DATA)*a_count,a_handle)
;If requested, sort the return data
if (^passed(a_sort)&&a_sort)
begin
using a_sort select
(WINDIR$SORT_NAME),
nop
(WINDIR$SORT_NAMEDESC),
xcall qsort(WINDIR$FILEDATA(a_handle,1),a_count,
& "WinDirSortNameDesc")
(WINDIR$SORT_SIZE),
xcall qsort(WINDIR$FILEDATA(a_handle,1),a_count,
& "WinDirSortSize")
(WINDIR$SORT_SIZEDESC),
xcall qsort(WINDIR$FILEDATA(a_handle,1),a_count,
& "WinDirSortSizeDesc")
endusing
end
end
end
;Close the DLL
dll = %dll_close(dll)
freturn status
;-----------------------------------------------------
;Populate return handle with data about this file
PopulateData,
WINDIR$FILENAME(a_handle,a_count)=FileName(1:(%instr(1,FileName,%char(0))-1))
if (^passed(a_case)&&a_case)
begin
case (a_case) of
begincase
WINDIR$UPPERCASE:
upcase WINDIR$FILENAME(a_handle,a_count)
WINDIR$LOWERCASE:
locase WINDIR$FILENAME(a_handle,a_count)
endcase
end
if (!FileSizeHigh) then
WINDIR$FILESIZE(a_handle,a_count) = %unsigned(FileSizeLow)
else
WINDIR$FILESIZE(a_handle,a_count) = (%unsigned(FileSizeHigh)
& * (4294967295+1)) + %unsigned(FileSizeLow)
WINDIR$ARCHIVE(a_handle,a_count) = FileAttributes & ATTR_ARCHIVE
WINDIR$HIDDEN(a_handle,a_count) = FileAttributes & ATTR_HIDDEN
WINDIR$READONLY(a_handle,a_count) = FileAttributes & ATTR_READONLY
WINDIR$SYSTEM(a_handle,a_count) = FileAttributes & ATTR_SYSTEM
return
;-----------------------------------------------------
;Create dynamic memory section if it doesn't exist
CreateArray,
if(!a_handle)
a_handle=%mem_proc(DM_ALLOC+DM_STATIC+DM_BLANK,
& ^size(WINDIR$DATA)*(mhs=INIT_SIZE))
return
;-----------------------------------------------------
;Resize dynamic memory section if necessary
ResizeArray,
;Resize dynamic memory?
if (a_count==mhs)
a_handle=%mem_proc(DM_RESIZ+DM_BLANK,
& ^size(WINDIR$DATA)*(mhs+=INCR_SIZE),a_handle)
return
.end
;****************************************************************************
.function WinDirSortNameDesc, ^val
file1 ,a
file2 ,a
.include "INC:WinDir.def"
.proc
if (^m(WINDIR$DATA.wd_filename,file2) < ^m(WINDIR$DATA.wd_filename,file1))
freturn(-1) ;Return element #1 < element #2
if (^m(WINDIR$DATA.wd_filename,file2) > ^m(WINDIR$DATA.wd_filename,file1))
freturn(1) ;Return element #1 > element #2
freturn(0)
.end
;****************************************************************************
.function WinDirSortSize, ^val
file1 ,a
file2 ,a
.include "INC:WinDir.def"
.proc
if (^m(WINDIR$DATA.wd_filesize,file1) < ^m(WINDIR$DATA.wd_filesize,file2))
freturn(-1) ;Return element #1 < element #2
if (^m(WINDIR$DATA.wd_filesize,file1) > ^m(WINDIR$DATA.wd_filesize,file2))
freturn(1) ;Return element #1 > element #2
freturn(0)
.end
;****************************************************************************
.function WinDirSortSizeDesc, ^val
file1 ,a
file2 ,a
.include "INC:WinDir.def"
.proc
if (^m(WINDIR$DATA.wd_filesize,file2) < ^m(WINDIR$DATA.wd_filesize,file1))
freturn(-1) ;Return element #1 < element #2
if (^m(WINDIR$DATA.wd_filesize,file2) > ^m(WINDIR$DATA.wd_filesize,file1))
freturn(1) ;Return element #1 > element #2
freturn(0)
.end
.endc ;DBLNET
.endc ;D_GUI