/
win32_fileinfo_c.c
executable file
·114 lines (93 loc) · 3.47 KB
/
win32_fileinfo_c.c
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
/******************************************************************************/
/* */
/* TypeRex OCaml Tools */
/* */
/* OCamlPro */
/* */
/* Copyright 2011-2012 OCamlPro */
/* All rights reserved. See accompanying files for the terms under */
/* which this file is distributed. In doubt, contact us at */
/* contact@ocamlpro.com (http://www.ocamlpro.com/) */
/* */
/******************************************************************************/
#ifdef ALSO__CYGWIN__
#define _WIN32
#endif
#ifdef _WIN32
#include <windows.h>
#include <sys/types.h>
#endif
#include <caml/mlvalues.h>
#include <caml/alloc.h>
#include <caml/unixsupport.h>
#include <caml/memory.h>
#include <caml/signals.h>
#ifdef _WIN32
DOUBLE FileTime_to_POSIX(FILETIME ft)
{
ULARGE_INTEGER date, adjust;
date.HighPart = ft.dwHighDateTime;
date.LowPart = ft.dwLowDateTime;
// 100-nanoseconds = milliseconds * 10000
adjust.QuadPart = 11644473600000ULL * 10000;
// removes the diff between 1970 and 1601
date.QuadPart -= adjust.QuadPart;
// converts back from 100-nanoseconds to seconds
return date.QuadPart / 1e7;
}
value win32_getFileInformationByHandle_ml(value handle_v)
{
HANDLE handle = (HANDLE)handle_v;
BY_HANDLE_FILE_INFORMATION fileInfo;
CAMLparam0 ();
CAMLlocal1 (v);
ULARGE_INTEGER size, index;
if( !GetFileInformationByHandle(handle, &fileInfo) ){
DWORD err = GetLastError();
win32_maperr(err);
uerror("GetFileInformationByHandle", Nothing);
}
size.HighPart = fileInfo.nFileSizeHigh;
size.LowPart = fileInfo.nFileSizeLow;
index.HighPart = fileInfo.nFileIndexHigh;
index.LowPart = fileInfo.nFileIndexLow;
v = caml_alloc (8, 0);
Store_field(v,0, Val_int(fileInfo.dwFileAttributes));
Store_field(v, 1,
caml_copy_double(FileTime_to_POSIX(fileInfo.ftCreationTime)));
Store_field(v, 2,
caml_copy_double(FileTime_to_POSIX(fileInfo.ftLastAccessTime)));
Store_field(v, 3,
caml_copy_double(FileTime_to_POSIX(fileInfo.ftLastWriteTime)));
Store_field(v, 4, Val_int(fileInfo.dwVolumeSerialNumber));
Store_field(v, 5, caml_copy_int64(size.QuadPart));
Store_field(v, 6, Val_int(fileInfo.nNumberOfLinks));
Store_field(v, 7, caml_copy_int64(index.QuadPart));
CAMLreturn (v);
}
value win32_getFileInformationByName_ml(value filename_v)
{
HANDLE hfile = CreateFile(String_val(filename_v), 0,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
value res;
if( hfile == INVALID_HANDLE_VALUE ){
DWORD err = GetLastError();
win32_maperr(err);
uerror("GetFileInformationByName", Nothing);
}
res = win32_getFileInformationByHandle_ml((value)hfile);
CloseHandle(hfile);
return res;
}
#else
value win32_getFileInformationByHandle_ml(value handle_v)
{
uerror("win32_getFileInformationByHandle_ml", Nothing);
}
value win32_getFileInformationByName_ml(value filename_v)
{
uerror("win32_getFileInformationByName_ml", Nothing);
}
#endif