patch #7365
[mldonkey.git] / src / config / mingw / os_stubs_c.c
blob1f67816fdebb7e79be3e4e8c77fb35585c6c8f6b
1 /* Copyright 2001, 2002 b8_bavard, b8_fee_carabine, INRIA */
2 /*
3 This file is part of mldonkey.
5 mldonkey is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 mldonkey 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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with mldonkey; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "../../utils/lib/os_stubs.h"
25 /*******************************************************************
28 os_read
31 *******************************************************************/
33 #define UNIX_BUFFER_SIZE 16384
35 extern void enter_blocking_section();
36 extern void leave_blocking_section();
38 extern ssize_t os_read(OS_FD fd, char *buf, size_t len)
40 DWORD numread;
41 BOOL ret;
43 if (len > UNIX_BUFFER_SIZE) len = UNIX_BUFFER_SIZE;
45 enter_blocking_section();
46 ret = ReadFile(fd, buf, len, &numread, NULL);
47 leave_blocking_section();
48 if (! ret) {
49 win32_maperr(GetLastError());
50 uerror("os_read", Nothing);
52 return numread;
55 /*******************************************************************
58 os_ftruncate
61 *******************************************************************/
63 #include <winioctl.h>
65 void os_ftruncate(OS_FD fd, OFF_T size, /* bool */ int sparse)
67 DWORD curpos;
68 long ofs_low = (long) size;
69 long ofs_high = (long) (size >> 32);
71 if (sparse) {
72 DWORD dw;
73 BOOL bRet = DeviceIoControl(fd, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dw, NULL);
74 if (!bRet) {
75 // No sparse files for you, sucker...
76 // DWORD err = GetLastError();
79 curpos = SetFilePointer (fd, 0, NULL, FILE_CURRENT);
80 if (curpos == 0xFFFFFFFF
81 || SetFilePointer (fd, ofs_low, &ofs_high, FILE_BEGIN) == 0xFFFFFFFF
82 || !SetEndOfFile (fd))
84 long err = GetLastError();
85 if (err != NO_ERROR) {
86 win32_maperr(err);
87 uerror("os_ftruncate", Nothing);
92 /*******************************************************************
95 os_getdtablesize
98 *******************************************************************/
100 int os_getdtablesize()
102 return 32767;
105 /*******************************************************************
108 os_getfdsize
111 *******************************************************************/
113 int64 os_getfdsize(OS_FD fd)
115 long len_high;
116 int64 ret;
118 ret = GetFileSize(fd, &len_high);
119 return ((int64) len_high << 32 | ret);
122 /*******************************************************************
125 os_getfilesize
128 *******************************************************************/
130 int64 os_getfilesize(char *path)
132 OS_FD fd = CreateFile(path, GENERIC_READ, FILE_SHARE_READ,
133 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
134 NULL);
135 long len_high;
136 long ret;
137 if (fd != INVALID_HANDLE_VALUE){
138 ret = GetFileSize(fd, &len_high);
139 CloseHandle(fd);
140 return ((int64) len_high << 32 | ret);
141 } else {
142 long err = GetLastError();
143 if (err != NO_ERROR) {
144 win32_maperr(err);
145 uerror("os_getfilesize", Nothing);
147 return 0;
151 /*******************************************************************
154 os_lseek
157 *******************************************************************/
159 OFF_T os_lseek(OS_FD fd, OFF_T ofs, int cmd)
161 DWORD ret;
162 long ofs_low = ofs;
163 long ofs_high = (long) (ofs >> 32);
164 long err;
166 ret = SetFilePointer(fd, ofs_low, &ofs_high, cmd);
167 if ((unsigned long)ret == INVALID_SET_FILE_POINTER) {
168 err = GetLastError();
169 if (err != NO_ERROR) {
170 win32_maperr(err);
171 uerror("os_lseek", Nothing);
174 return ((OFF_T) ofs_high << 32 | ret);
177 /*******************************************************************
180 os_set_nonblock
183 *******************************************************************/
185 #include <winsock2.h>
187 void os_set_nonblock(OS_SOCKET fd)
189 u_long optval = 1;
191 if( ioctlsocket(fd, FIONBIO, &optval) != 0){
192 long err = GetLastError();
193 if (err != NO_ERROR) {
194 win32_maperr(err);
195 uerror("os_set_nonblock", Nothing);
200 /*******************************************************************
203 os_uname
206 *******************************************************************/
208 // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getting_the_system_version.asp
209 #define BUFSIZE 80
210 #define SM_SERVERR2 89
211 typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
214 void os_uname(char buf[])
216 OSVERSIONINFOEX osvi;
217 BOOL bOsVersionInfoEx;
218 SYSTEM_INFO si;
219 PGNSI pGNSI;
220 char tbuf[4096];
221 char pbuf[32];
222 char binull='\0';
224 // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
225 // If that fails, try using the OSVERSIONINFO structure.
227 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
228 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
230 if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
232 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
233 if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
234 return;
237 switch (osvi.dwPlatformId)
239 // Test for the Windows NT product family.
240 case VER_PLATFORM_WIN32_NT:
242 // Test for the specific product.
243 if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 )
245 if( osvi.wProductType == VER_NT_WORKSTATION )
246 strcat (buf, "Microsoft Windows Vista \0");
247 else strcat (buf, "Windows Server \"Longhorn\" \0" );
250 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
252 // Use GetProcAddress to avoid load issues on Windows 2000
253 pGNSI = (PGNSI) GetProcAddress (GetModuleHandle("kernel32.dll"), "GetNativeSystemInfo");
254 if(NULL != pGNSI)
255 pGNSI(&si);
257 if( GetSystemMetrics(SM_SERVERR2) )
258 strcat (buf, "Microsoft Windows Server 2003 \"R2\" \0");
259 else if( osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
261 strcat (buf, "Microsoft Windows XP Professional x64 Edition \0");
263 else strcat (buf, "Microsoft Windows Server 2003, \0");
266 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
267 strcat(buf, "Microsoft Windows XP \0");
269 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
270 strcat(buf, "Microsoft Windows 2000 \0");
272 if ( osvi.dwMajorVersion <= 4 )
273 strcat(buf, "Microsoft Windows NT \0");
275 // Test for specific product on Windows NT 4.0 SP6 and later.
276 if( bOsVersionInfoEx )
278 // Test for the workstation type.
279 if ( osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_AMD64 )
281 if( osvi.dwMajorVersion == 4 )
282 strcat(buf, "Workstation 4.0 \0" );
283 else if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
284 strcat(buf, "Home Edition \0" );
285 else strcat(buf, "Professional \0" );
288 // Test for the server type.
289 else if ( osvi.wProductType == VER_NT_SERVER ||
290 osvi.wProductType == VER_NT_DOMAIN_CONTROLLER )
292 if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
294 if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 )
296 if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
297 strcat (buf, "Datacenter Edition for Itanium-based Systems \0" );
298 else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
299 strcat (buf, "Enterprise Edition for Itanium-based Systems \0" );
302 else if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 )
304 if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
305 strcat (buf, "Datacenter x64 Edition \0" );
306 else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
307 strcat (buf, "Enterprise x64 Edition \0" );
308 else strcat (buf, "Standard x64 Edition \0" );
311 else
313 if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
314 strcat (buf, "Datacenter Edition \0" );
315 else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
316 strcat (buf, "Enterprise Edition \0" );
317 else if ( osvi.wSuiteMask == VER_SUITE_BLADE )
318 strcat (buf, "Web Edition \0" );
319 else strcat (buf, "Standard Edition \0" );
323 else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
325 if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
326 strcat(buf, "Datacenter Server \0" );
327 else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
328 strcat(buf, "Advanced Server \0" );
329 else strcat(buf, "Server \0" );
331 else // Windows NT 4.0
333 if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
334 strcat(buf, "Server 4.0, Enterprise Edition \0" );
335 else strcat(buf, "Server 4.0 \0" );
339 // Test for specific product on Windows NT 4.0 SP5 and earlier
340 else
342 HKEY hKey;
343 char szProductType[BUFSIZE];
344 DWORD dwBufLen=BUFSIZE;
345 LONG lRet;
347 lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
348 "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
349 0, KEY_QUERY_VALUE, &hKey );
350 if( lRet != ERROR_SUCCESS )
351 return;
353 lRet = RegQueryValueEx( hKey, "ProductType", NULL, NULL,
354 (LPBYTE) szProductType, &dwBufLen);
355 if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) )
356 return;
358 RegCloseKey( hKey );
360 if ( lstrcmpi( "WINNT", szProductType) == 0 )
361 strcat(buf, "Workstation \0" );
362 if ( lstrcmpi( "LANMANNT", szProductType) == 0 )
363 strcat(buf, "Server \0" );
364 if ( lstrcmpi( "SERVERNT", szProductType) == 0 )
365 strcat(buf, "Advanced Server \0" );
366 sprintf(tbuf, "%d.%d %c", (int)osvi.dwMajorVersion, (int)osvi.dwMinorVersion, binull );
369 // Display service pack (if any), build number and processor count (if it`s > 1).
371 GetSystemInfo(&si);
373 if( si.dwNumberOfProcessors > 1)
375 sprintf(pbuf, "(CPUs: %lu)%c", si.dwNumberOfProcessors, binull);
376 else
377 pbuf[0] = binull;
380 if( osvi.dwMajorVersion == 4 && lstrcmpi( osvi.szCSDVersion, "Service Pack 6" ) == 0 )
382 HKEY hKey;
383 LONG lRet;
385 // Test for SP6 versus SP6a.
386 lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
387 "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009",
388 0, KEY_QUERY_VALUE, &hKey );
389 if( lRet == ERROR_SUCCESS )
391 sprintf(tbuf, "Service Pack 6a (Build %lu) %s", osvi.dwBuildNumber & 0xFFFF, pbuf );
392 else // Windows NT 4.0 prior to SP6a
394 sprintf(tbuf, "%s (Build %lu) %s",osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF, pbuf);
396 RegCloseKey( hKey );
398 else // not Windows NT 4.0
400 sprintf(tbuf, "%s (Build %lu) %s", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF, pbuf);
403 strcat(buf, tbuf);
404 break;
406 // Test for the Windows Me/98/95.
407 case VER_PLATFORM_WIN32_WINDOWS:
409 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
411 strcat (buf, "Microsoft Windows 95 ");
412 if (osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B')
413 strcat(buf, "OSR2 \0" );
416 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
418 strcat(buf, "Microsoft Windows 98 ");
419 if ( osvi.szCSDVersion[1] == 'A' )
420 strcat(buf, "SE \0" );
423 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
425 strcat(buf, "Microsoft Windows Millennium Edition\0");
427 break;
429 case VER_PLATFORM_WIN32s:
431 strcat(buf, "Microsoft Win32s\0");
432 break;
434 return;
437 /*******************************************************************
440 os_os_supported
443 *******************************************************************/
445 int os_os_supported()
447 OSVERSIONINFO pVersion;
448 pVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
449 int check = GetVersionEx(&pVersion);
451 if ( check != 0 )
453 if ( pVersion.dwPlatformId == VER_PLATFORM_WIN32_NT )
454 return 1;
455 else
456 return 0;
458 else /* expect an NT system because GetVersionEx failed */
460 return 1;
464 /*******************************************************************
467 os_set_console_title
470 *******************************************************************/
472 value os_set_console_title(value buf)
474 char *pbuf = String_val (buf);
476 SetConsoleTitle((LPCTSTR)pbuf);
477 return Val_unit;
480 int os_fsync(OS_FD fd)
482 int r = FlushFileBuffers(fd);
483 return (0 == r ? -1 : 0);