// Description   : Windows bindings for the NANO OS Core $Revision: 9 $

// Copyright     : Proxima Centauri Romania SRL, ALL RIGHTS RESERVED. (http://www.ProximaCentauri.org)

// Author        : Alexander Ioan Mihail

 

#include "CORE/Nano.h"

#include <windows.h>

#include <process.h>

 

void PACKAGE ApiError(char*msg)

{

      char error_str[1024];

      FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError(),0,error_str,sizeof(error_str),0);

      TRACE((TRACE_ERROR,0,"%s %s",msg,error_str));

}

void PACKAGE OurSleep(int msecs)

{

      Sleep(msecs);

}

int PACKAGE OurWaitForMultipleObjects(int nCount,void** lpHandles,int bWaitAll,int dwMilliseconds)

{

      return WaitForMultipleObjects(nCount,(HANDLE*)lpHandles,bWaitAll,dwMilliseconds);

}

int GetCurrentPID()

{

      return GetCurrentProcessId();

}

PACKAGE void*init_shared_memory(const char*fname,void*address,int size)

{

      char error_str[1000];

 

      SECURITY_DESCRIPTOR sd = {0};

      InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);

      SetSecurityDescriptorDacl(&sd,TRUE,(PACL)NULL, FALSE);

      SECURITY_ATTRIBUTES sa;

      sa.nLength = sizeof(SECURITY_ATTRIBUTES);

      sa.bInheritHandle = TRUE;

      sa.lpSecurityDescriptor = &sd;

      HANDLE hMMFile=CreateFileMappingA

      (

            (void*)-1,

            &sa,

            PAGE_READWRITE,

            0,

            size,

            fname

      );

  if (!hMMFile)

      {

            FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError(),0,error_str,sizeof(error_str),0);

            TRACE((TRACE_ERROR,0,"Cound not create file mapping",fname,error_str));

            return nullptr;

      }

      void*ptr=MapViewOfFileEx

      (

            hMMFile,

            FILE_MAP_READ|FILE_MAP_WRITE,

            0,0,

            size,

            address

      );

  if (ptr!=nullptr)

  {

    if (ptr==address)

      return hMMFile;

            TRACE((TRACE_ERROR,0,"File %s mapped to address %X instead of %X.\r\n",fname,ptr,address));

  }  

  else

      {

            FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError(),0,error_str,sizeof(error_str),0);

            TRACE((TRACE_ERROR,0,"Error %s mapping file %s to address %X.\r\n",error_str,fname,address));

      }

      CloseHandle(hMMFile);

      return nullptr;

}

void PACKAGE done_shared_memory(void*hmem)

{

   if (hmem)

            CloseHandle(hmem);

}

bool PACKAGE SendUsbCommand(char*path,char*cmd,int len)

{

      HANDLE h=CreateFileA(path, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);

      if (h==INVALID_HANDLE_VALUE)

            return false;

      unsigned long bytesWritten;

      if (!WriteFile(h, cmd, len, &bytesWritten, 0))

            ApiError("SendUsbCommand");

      CloseHandle(h);

      return true;

}

PACKAGE char*GetCurrentUserName()

{

      static char buf[1000];

      DWORD nsize=sizeof(buf);

      GetUserNameA(buf,&nsize);

      return buf; // pointer must not be deleted.

}

PACKAGE unsigned long OurGetLogicalDrives()

{

    return GetLogicalDrives();

}

PACKAGE bool IsDriveRemote(char*root_path)

{

    return (GetDriveTypeA(root_path)==DRIVE_REMOTE);

}

PACKAGE bool GetVolumeName(char*root_path,char*volume_name,int sz)

{

    unsigned long  MaximumComponentLength=0;

    unsigned long  FileSystemFlags;

    char  fs_name[20];

    return  (GetVolumeInformationA

         (

          root_path,

          volume_name,

          sz,

          NULL,

          &MaximumComponentLength,

          &FileSystemFlags,

          fs_name,

          sizeof(fs_name)

         )

        );

}

PACKAGE void* Buffer2Bmp(char*image)

{

   BITMAPFILEHEADER*bmfh=(BITMAPFILEHEADER*)image;

   if (bmfh->bfType!=0x4d42) // BM

    return 0;

   BITMAPINFO*bmi=(BITMAPINFO*)((char*)image+sizeof(BITMAPFILEHEADER));

   void*bits=((LPSTR)image+bmfh->bfOffBits);

   BITMAP bm;

   bm.bmType=0;

   bm.bmWidth=bmi->bmiHeader.biWidth;

   bm.bmHeight=bmi->bmiHeader.biHeight;

   bm.bmPlanes=bmi->bmiHeader.biPlanes;

   bm.bmBitsPixel=bmi->bmiHeader.biBitCount;

   bm.bmWidthBytes=(bm.bmWidth*bm.bmBitsPixel+31)/32*4;

   bm.bmBits=bits;

   HBITMAP hbmp;

   HDC hdc = GetDC(0);

   static int algorithm=2;

   if (algorithm==0)

   {

    hbmp=CreateBitmap(bm.bmWidth,bm.bmHeight,bm.bmPlanes,bm.bmBitsPixel,bits);

   } else if (algorithm==1)

   {

    hbmp=CreateBitmapIndirect(&bm);

    SetDIBits(hdc,hbmp,0,bm.bmHeight,bits,bmi,DIB_RGB_COLORS);

   } else if (algorithm==2)

    hbmp=CreateDIBitmap(hdc, &bmi->bmiHeader, CBM_INIT, bits, bmi, DIB_RGB_COLORS);

   else if (algorithm==4)

   {

    hbmp = CreateCompatibleBitmap(hdc,(WORD)bm.bmWidth,bm.bmHeight);

    SetDIBits(hdc,hbmp,0,bm.bmHeight,bits,bmi,DIB_RGB_COLORS);

   } else if (algorithm==5)

    hbmp = CreateDIBSection(hdc,bmi,DIB_RGB_COLORS,&bits,NULL,0);

 

   if (!hbmp)

   {

    ApiError("Bitmap null");

    DeleteDC(hdc);

    return 0;

   }

   GetObject(hbmp, sizeof(BITMAP), (LPSTR)&bm);

   ReleaseDC(0,hdc);

   return hbmp;

}

 

unsigned int tls_index=0xffffffff;

extern "C" void* GetTlsData()

{

  return TlsGetValue(tls_index);

}