blob: 80219c6ba121a8b98183f7794007ae4a713f3ce8 [file] [log] [blame]
/*
* Win32 miscellaneous functions
*
* Copyright 1995 Thomas Sandford (tdgsandf@prds-grn.demon.co.uk)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Misc. new functions - they should be moved into appropriate files
at a later date. */
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winerror.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(win32);
WINE_DECLARE_DEBUG_CHANNEL(debug);
static BOOL QUERYPERF_Initialized = 0;
#if defined(__i386__) && defined(__GNUC__)
static BOOL QUERYPERF_RDTSC_Use = 0;
static LONGLONG QUERYPERF_RDTSC_Frequency = 0;
#endif
static void QUERYPERF_Init(void)
{
#if defined(__i386__) && defined(__GNUC__)
/* We are running on i386 and compiling on GCC.
* Do a runtime check to see if we have the rdtsc instruction available
*/
FILE *fp;
char line[256], *s, *value;
double cpuMHz;
TRACE("()\n");
if (IsProcessorFeaturePresent( PF_RDTSC_INSTRUCTION_AVAILABLE ))
{
/* rdtsc is available. However, in order to use it
* we also need to be able to get the processor's
* speed. Currently we do this by reading /proc/cpuinfo
* which makes it Linux-specific.
*/
TRACE("rdtsc available\n");
fp = fopen( "/proc/cpuinfo", "r" );
if (fp)
{
while(fgets( line, sizeof(line), fp ))
{
/* NOTE: the ':' is the only character we can rely on */
if (!(value = strchr( line, ':' )))
continue;
/* terminate the valuename */
*value++ = '\0';
/* skip any leading spaces */
while (*value == ' ') value++;
if ((s = strchr( value, '\n' )))
*s = '\0';
if (!strncasecmp( line, "cpu MHz", strlen( "cpu MHz" ) ))
{
if (sscanf( value, "%lf", &cpuMHz ) == 1)
{
QUERYPERF_RDTSC_Frequency = (LONGLONG)(cpuMHz * 1000000.0);
QUERYPERF_RDTSC_Use = TRUE;
TRACE("using frequency: %lldHz\n", QUERYPERF_RDTSC_Frequency);
break;
}
}
}
fclose(fp);
}
}
#endif
QUERYPERF_Initialized = TRUE;
}
/****************************************************************************
* QueryPerformanceCounter (KERNEL32.@)
*/
BOOL WINAPI QueryPerformanceCounter(PLARGE_INTEGER counter)
{
struct timeval tv;
if (!QUERYPERF_Initialized)
QUERYPERF_Init();
#if defined(__i386__) && defined(__GNUC__)
if (QUERYPERF_RDTSC_Use)
{
/* i586 optimized version */
__asm__ __volatile__ ( "rdtsc"
: "=a" (counter->s.LowPart), "=d" (counter->s.HighPart) );
return TRUE;
}
/* fall back to generic routine (ie, for i386, i486) */
#endif
/* generic routine */
gettimeofday( &tv, NULL );
counter->QuadPart = (LONGLONG)tv.tv_usec + (LONGLONG)tv.tv_sec * 1000000LL;
return TRUE;
}
/****************************************************************************
* QueryPerformanceFrequency (KERNEL32.@)
*/
BOOL WINAPI QueryPerformanceFrequency(PLARGE_INTEGER frequency)
{
if (!QUERYPERF_Initialized)
QUERYPERF_Init();
#if defined(__i386__) && defined(__GNUC__)
if (QUERYPERF_RDTSC_Use)
{
frequency->QuadPart = QUERYPERF_RDTSC_Frequency;
return TRUE;
}
#endif
frequency->s.LowPart = 1000000;
frequency->s.HighPart = 0;
return TRUE;
}
/****************************************************************************
* FlushInstructionCache (KERNEL32.@)
*/
BOOL WINAPI FlushInstructionCache(HANDLE hProcess, LPCVOID lpBaseAddress, DWORD dwSize)
{
if (GetVersion() & 0x80000000) return TRUE; /* not NT, always TRUE */
FIXME_(debug)("(0x%08lx,%p,0x%08lx): stub\n",(DWORD)hProcess, lpBaseAddress, dwSize);
return TRUE;
}
/***********************************************************************
* GetSystemPowerStatus (KERNEL32.@)
*/
BOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS sps_ptr)
{
return FALSE; /* no power management support */
}
/***********************************************************************
* SetSystemPowerState (KERNEL32.@)
*/
BOOL WINAPI SetSystemPowerState(BOOL suspend_or_hibernate,
BOOL force_flag)
{
/* suspend_or_hibernate flag: w95 does not support
this feature anyway */
for ( ;0; )
{
if ( force_flag )
{
}
else
{
}
}
return TRUE;
}
/******************************************************************************
* CreateMailslotA [KERNEL32.@]
*/
HANDLE WINAPI CreateMailslotA( LPCSTR lpName, DWORD nMaxMessageSize,
DWORD lReadTimeout, LPSECURITY_ATTRIBUTES sa)
{
FIXME("(%s,%ld,%ld,%p): stub\n", debugstr_a(lpName),
nMaxMessageSize, lReadTimeout, sa);
return 1;
}
/******************************************************************************
* CreateMailslotW [KERNEL32.@] Creates a mailslot with specified name
*
* PARAMS
* lpName [I] Pointer to string for mailslot name
* nMaxMessageSize [I] Maximum message size
* lReadTimeout [I] Milliseconds before read time-out
* sa [I] Pointer to security structure
*
* RETURNS
* Success: Handle to mailslot
* Failure: INVALID_HANDLE_VALUE
*/
HANDLE WINAPI CreateMailslotW( LPCWSTR lpName, DWORD nMaxMessageSize,
DWORD lReadTimeout, LPSECURITY_ATTRIBUTES sa )
{
FIXME("(%s,%ld,%ld,%p): stub\n", debugstr_w(lpName),
nMaxMessageSize, lReadTimeout, sa);
return 1;
}
/******************************************************************************
* GetMailslotInfo [KERNEL32.@] Retrieves info about specified mailslot
*
* PARAMS
* hMailslot [I] Mailslot handle
* lpMaxMessageSize [O] Address of maximum message size
* lpNextSize [O] Address of size of next message
* lpMessageCount [O] Address of number of messages
* lpReadTimeout [O] Address of read time-out
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI GetMailslotInfo( HANDLE hMailslot, LPDWORD lpMaxMessageSize,
LPDWORD lpNextSize, LPDWORD lpMessageCount,
LPDWORD lpReadTimeout )
{
FIXME("(%04x): stub\n",hMailslot);
if (lpMaxMessageSize) *lpMaxMessageSize = (DWORD)NULL;
if (lpNextSize) *lpNextSize = (DWORD)NULL;
if (lpMessageCount) *lpMessageCount = (DWORD)NULL;
if (lpReadTimeout) *lpReadTimeout = (DWORD)NULL;
return TRUE;
}
/******************************************************************************
* GetCompressedFileSizeA [KERNEL32.@]
*
* NOTES
* This should call the W function below
*/
DWORD WINAPI GetCompressedFileSizeA(
LPCSTR lpFileName,
LPDWORD lpFileSizeHigh)
{
FIXME("(...): stub\n");
return 0xffffffff;
}
/******************************************************************************
* GetCompressedFileSizeW [KERNEL32.@]
*
* RETURNS
* Success: Low-order doubleword of number of bytes
* Failure: 0xffffffff
*/
DWORD WINAPI GetCompressedFileSizeW(
LPCWSTR lpFileName, /* [in] Pointer to name of file */
LPDWORD lpFileSizeHigh) /* [out] Receives high-order doubleword of size */
{
FIXME("(%s,%p): stub\n",debugstr_w(lpFileName),lpFileSizeHigh);
return 0xffffffff;
}
/******************************************************************************
* SetComputerNameA [KERNEL32.@]
*/
BOOL WINAPI SetComputerNameA( LPCSTR lpComputerName )
{
BOOL ret;
DWORD len = MultiByteToWideChar( CP_ACP, 0, lpComputerName, -1, NULL, 0 );
LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, lpComputerName, -1, nameW, len );
ret = SetComputerNameW( nameW );
HeapFree( GetProcessHeap(), 0, nameW );
return ret;
}
/******************************************************************************
* SetComputerNameW [KERNEL32.@]
*
* PARAMS
* lpComputerName [I] Address of new computer name
*
* RETURNS STD
*/
BOOL WINAPI SetComputerNameW( LPCWSTR lpComputerName )
{
FIXME("(%s): stub\n", debugstr_w(lpComputerName));
return TRUE;
}
/******************************************************************************
* CreateIoCompletionPort (KERNEL32.@)
*/
HANDLE WINAPI CreateIoCompletionPort(HANDLE hFileHandle,
HANDLE hExistingCompletionPort, DWORD dwCompletionKey,
DWORD dwNumberOfConcurrentThreads)
{
FIXME("(%04x, %04x, %08lx, %08lx): stub.\n", hFileHandle, hExistingCompletionPort, dwCompletionKey, dwNumberOfConcurrentThreads);
return (HANDLE)NULL;
}
/******************************************************************************
* GetQueuedCompletionStatus (KERNEL32.@)
*/
BOOL WINAPI GetQueuedCompletionStatus(
HANDLE CompletionPort, LPDWORD lpNumberOfBytesTransferred,
LPDWORD lpCompletionKey, LPOVERLAPPED *lpOverlapped, DWORD dwMilliseconds
) {
FIXME("(%x,%p,%p,%p,%ld), stub!\n",CompletionPort,lpNumberOfBytesTransferred,lpCompletionKey,lpOverlapped,dwMilliseconds);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}