]> gitweb.factorcode.org Git - factor.git/blob - basis/io/windows/files/files.factor
Fix permission bits
[factor.git] / basis / io / windows / files / files.factor
1 ! Copyright (C) 2008 Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: alien.c-types io.binary io.backend io.files io.buffers
4 io.windows kernel math splitting
5 windows windows.kernel32 windows.time calendar combinators
6 math.functions sequences namespaces make words symbols system
7 io.ports destructors accessors math.bitwise ;
8 IN: io.windows.files
9
10 : open-file ( path access-mode create-mode flags -- handle )
11     [
12         >r >r share-mode default-security-attributes r> r>
13         CreateFile-flags f CreateFile opened-file
14     ] with-destructors ;
15
16 : open-pipe-r/w ( path -- win32-file )
17     { GENERIC_READ GENERIC_WRITE } flags
18     OPEN_EXISTING 0 open-file ;
19
20 : open-read ( path -- win32-file )
21     GENERIC_READ OPEN_EXISTING 0 open-file 0 >>ptr ;
22
23 : open-write ( path -- win32-file )
24     GENERIC_WRITE CREATE_ALWAYS 0 open-file 0 >>ptr ;
25
26 : (open-append) ( path -- win32-file )
27     GENERIC_WRITE OPEN_ALWAYS 0 open-file ;
28
29 : open-existing ( path -- win32-file )
30     { GENERIC_READ GENERIC_WRITE } flags
31     share-mode
32     f
33     OPEN_EXISTING
34     FILE_FLAG_BACKUP_SEMANTICS
35     f CreateFileW dup win32-error=0/f <win32-file> ;
36
37 : maybe-create-file ( path -- win32-file ? )
38     #! return true if file was just created
39     { GENERIC_READ GENERIC_WRITE } flags
40     share-mode
41     f
42     OPEN_ALWAYS
43     0 CreateFile-flags
44     f CreateFileW dup win32-error=0/f <win32-file>
45     GetLastError ERROR_ALREADY_EXISTS = not ;
46
47 : set-file-pointer ( handle length method -- )
48     >r dupd d>w/w <uint> r> SetFilePointer
49     INVALID_SET_FILE_POINTER = [
50         CloseHandle "SetFilePointer failed" throw
51     ] when drop ;
52
53 HOOK: open-append os ( path -- win32-file )
54
55 TUPLE: FileArgs
56     hFile lpBuffer nNumberOfBytesToRead
57     lpNumberOfBytesRet lpOverlapped ;
58
59 C: <FileArgs> FileArgs
60
61 : make-FileArgs ( port -- <FileArgs> )
62     {
63         [ handle>> check-disposed ]
64         [ handle>> handle>> ]
65         [ buffer>> ]
66         [ buffer>> buffer-length ]
67         [ drop "DWORD" <c-object> ]
68         [ FileArgs-overlapped ]
69     } cleave <FileArgs> ;
70
71 : setup-read ( <FileArgs> -- hFile lpBuffer nNumberOfBytesToRead lpNumberOfBytesRead lpOverlapped )
72     {
73         [ hFile>> ]
74         [ lpBuffer>> buffer-end ]
75         [ lpBuffer>> buffer-capacity ]
76         [ lpNumberOfBytesRet>> ]
77         [ lpOverlapped>> ]
78     } cleave ;
79
80 : setup-write ( <FileArgs> -- hFile lpBuffer nNumberOfBytesToWrite lpNumberOfBytesWritten lpOverlapped )
81     {
82         [ hFile>> ]
83         [ lpBuffer>> buffer@ ]
84         [ lpBuffer>> buffer-length ]
85         [ lpNumberOfBytesRet>> ]
86         [ lpOverlapped>> ]
87     } cleave ;
88
89 M: windows (file-reader) ( path -- stream )
90     open-read <input-port> ;
91
92 M: windows (file-writer) ( path -- stream )
93     open-write <output-port> ;
94
95 M: windows (file-appender) ( path -- stream )
96     open-append <output-port> ;
97
98 M: windows move-file ( from to -- )
99     [ normalize-path ] bi@ MoveFile win32-error=0/f ;
100
101 M: windows delete-file ( path -- )
102     normalize-path DeleteFile win32-error=0/f ;
103
104 M: windows copy-file ( from to -- )
105     dup parent-directory make-directories
106     [ normalize-path ] bi@ 0 CopyFile win32-error=0/f ;
107
108 M: windows make-directory ( path -- )
109     normalize-path
110     f CreateDirectory win32-error=0/f ;
111
112 M: windows delete-directory ( path -- )
113     normalize-path
114     RemoveDirectory win32-error=0/f ;
115
116 M: windows normalize-directory ( string -- string )
117     normalize-path "\\" ?tail drop "\\*" append ;
118
119 SYMBOLS: +read-only+ +hidden+ +system+
120 +archive+ +device+ +normal+ +temporary+
121 +sparse-file+ +reparse-point+ +compressed+ +offline+
122 +not-content-indexed+ +encrypted+ ;
123
124 : win32-file-attribute ( n attr symbol -- n )
125     >r dupd mask? r> swap [ , ] [ drop ] if ;
126
127 : win32-file-attributes ( n -- seq )
128     [
129         FILE_ATTRIBUTE_READONLY +read-only+ win32-file-attribute
130         FILE_ATTRIBUTE_HIDDEN +hidden+ win32-file-attribute
131         FILE_ATTRIBUTE_SYSTEM +system+ win32-file-attribute
132         FILE_ATTRIBUTE_DIRECTORY +directory+ win32-file-attribute
133         FILE_ATTRIBUTE_ARCHIVE +archive+ win32-file-attribute
134         FILE_ATTRIBUTE_DEVICE +device+ win32-file-attribute
135         FILE_ATTRIBUTE_NORMAL +normal+ win32-file-attribute
136         FILE_ATTRIBUTE_TEMPORARY +temporary+ win32-file-attribute
137         FILE_ATTRIBUTE_SPARSE_FILE +sparse-file+ win32-file-attribute
138         FILE_ATTRIBUTE_REPARSE_POINT +reparse-point+ win32-file-attribute
139         FILE_ATTRIBUTE_COMPRESSED +compressed+ win32-file-attribute
140         FILE_ATTRIBUTE_OFFLINE +offline+ win32-file-attribute
141         FILE_ATTRIBUTE_NOT_CONTENT_INDEXED +not-content-indexed+ win32-file-attribute
142         FILE_ATTRIBUTE_ENCRYPTED +encrypted+ win32-file-attribute
143         drop
144     ] { } make ;
145
146 : win32-file-type ( n -- symbol )
147     FILE_ATTRIBUTE_DIRECTORY mask? +directory+ +regular-file+ ? ;
148
149 : WIN32_FIND_DATA>file-info ( WIN32_FIND_DATA -- file-info )
150     {
151         [ WIN32_FIND_DATA-dwFileAttributes win32-file-type ]
152         [
153             [ WIN32_FIND_DATA-nFileSizeLow ]
154             [ WIN32_FIND_DATA-nFileSizeHigh ] bi >64bit
155         ]
156         [ WIN32_FIND_DATA-dwFileAttributes ]
157         ! [ WIN32_FIND_DATA-ftCreationTime FILETIME>timestamp ]
158         [ WIN32_FIND_DATA-ftLastWriteTime FILETIME>timestamp ]
159         ! [ WIN32_FIND_DATA-ftLastAccessTime FILETIME>timestamp ]
160     } cleave
161     \ file-info boa ;
162
163 : find-first-file-stat ( path -- WIN32_FIND_DATA )
164     "WIN32_FIND_DATA" <c-object> [
165         FindFirstFile
166         [ INVALID_HANDLE_VALUE = [ win32-error ] when ] keep
167         FindClose win32-error=0/f
168     ] keep ;
169
170 : BY_HANDLE_FILE_INFORMATION>file-info ( HANDLE_FILE_INFORMATION -- file-info )
171     {
172         [ BY_HANDLE_FILE_INFORMATION-dwFileAttributes win32-file-type ]
173         [
174             [ BY_HANDLE_FILE_INFORMATION-nFileSizeLow ]
175             [ BY_HANDLE_FILE_INFORMATION-nFileSizeHigh ] bi >64bit
176         ]
177         [ BY_HANDLE_FILE_INFORMATION-dwFileAttributes ]
178         ! [ BY_HANDLE_FILE_INFORMATION-ftCreationTime FILETIME>timestamp ]
179         [ BY_HANDLE_FILE_INFORMATION-ftLastWriteTime FILETIME>timestamp ]
180         ! [ BY_HANDLE_FILE_INFORMATION-ftLastAccessTime FILETIME>timestamp ]
181         ! [ BY_HANDLE_FILE_INFORMATION-nNumberOfLinks ]
182         ! [
183           ! [ BY_HANDLE_FILE_INFORMATION-nFileIndexLow ]
184           ! [ BY_HANDLE_FILE_INFORMATION-nFileIndexHigh ] bi >64bit
185         ! ]
186     } cleave
187     \ file-info boa ;
188
189 : get-file-information ( handle -- BY_HANDLE_FILE_INFORMATION )
190     [
191         "BY_HANDLE_FILE_INFORMATION" <c-object>
192         [ GetFileInformationByHandle win32-error=0/f ] keep
193     ] keep CloseHandle win32-error=0/f ;
194
195 : get-file-information-stat ( path -- BY_HANDLE_FILE_INFORMATION )
196     dup
197     GENERIC_READ FILE_SHARE_READ f
198     OPEN_EXISTING FILE_FLAG_BACKUP_SEMANTICS f
199     CreateFileW dup INVALID_HANDLE_VALUE = [
200         drop find-first-file-stat WIN32_FIND_DATA>file-info
201     ] [
202         nip
203         get-file-information BY_HANDLE_FILE_INFORMATION>file-info
204     ] if ;
205
206 M: winnt file-info ( path -- info )
207     normalize-path get-file-information-stat ;
208
209 M: winnt link-info ( path -- info )
210     file-info ;
211
212 : file-times ( path -- timestamp timestamp timestamp )
213     [
214         normalize-path open-existing &dispose handle>>
215         "FILETIME" <c-object>
216         "FILETIME" <c-object>
217         "FILETIME" <c-object>
218         [ GetFileTime win32-error=0/f ] 3keep
219         [ FILETIME>timestamp >local-time ] tri@
220     ] with-destructors ;
221
222 : (set-file-times) ( handle timestamp/f timestamp/f timestamp/f -- )
223     [ timestamp>FILETIME ] tri@
224     SetFileTime win32-error=0/f ;
225
226 : set-file-times ( path timestamp/f timestamp/f timestamp/f -- )
227     #! timestamp order: creation access write
228     [
229         >r >r >r
230             normalize-path open-existing &dispose handle>>
231         r> r> r> (set-file-times)
232     ] with-destructors ;
233
234 : set-file-create-time ( path timestamp -- )
235     f f set-file-times ;
236
237 : set-file-access-time ( path timestamp -- )
238     >r f r> f set-file-times ;
239
240 : set-file-write-time ( path timestamp -- )
241     >r f f r> set-file-times ;
242
243 M: winnt touch-file ( path -- )
244     [
245         normalize-path
246         maybe-create-file >r &dispose r>
247         [ drop ] [ handle>> f now dup (set-file-times) ] if
248     ] with-destructors ;