⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 open.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
      case 1: SetStdHandle(STD_OUTPUT_HANDLE, hand); break;
      case 2: SetStdHandle(STD_ERROR_HANDLE,  hand); break;
   }

   return fd;
}


/*
 * INTERNAL: Allocate an fd slot from a Win32 HANDLE
 */
int alloc_fd(HANDLE hand, char flag)
{
  int ret;

  LOCK_FILES();

//  TRACE(":handle (%p) allocating fd (%d)\n",hand,MSVCRT_fdstart);
  ret = alloc_fd_from(hand, flag, g_fdstart);

  UNLOCK_FILES();
  return ret;
}



/*
 * INTERNAL
 */
char __fileno_getmode(int fd)
{
    if (!is_valid_fd(fd)) {
        __set_errno(EBADF);
        return -1;
    }
    return fdinfo(fd)->fdflags;

}

/*
 * INTERNAL
 */
void free_fd(int fd)
{
   LOCK_FILES();


   fdinfo(fd)->hFile = INVALID_HANDLE_VALUE;
   fdinfo(fd)->fdflags = 0;

   if (fd < 3) /* don't use 0,1,2 for user files */
   {
      switch (fd)
      {
         case 0: SetStdHandle(STD_INPUT_HANDLE,  NULL); break;
         case 1: SetStdHandle(STD_OUTPUT_HANDLE, NULL); break;
         case 2: SetStdHandle(STD_ERROR_HANDLE,  NULL); break;
      }
   }
   else
   {
      if (fd == g_fdend - 1)
         g_fdend--;

      if (fd < g_fdstart)
         g_fdstart = fd;
   }


   UNLOCK_FILES();
}

/*
 * @implemented
 */
int _open_osfhandle(long osfhandle, int oflags)
{
   /*
   PREV:
   The _open_osfhandle() function in MSVCRT is expected to take the absence
   of either _O_TEXT or _O_BINARY to mean _O_BINARY. Currently it defaults to
   _O_TEXT.

   An example of this is MFC's CStdioFile::Open in binary mode - it passes flags
   of 0 when it wants to write a binary file - under WINE we do text mode conversions!

   The attached patch ensures that _O_BINARY is set if neither is set in the passed-in
flags.


   * file, so set the write flag. It also only sets _O_TEXT if it wants
   * text - it never sets _O_BINARY.
    */
   /* FIXME: handle more flags */
/*
  flags |= MSVCRT__IOREAD|MSVCRT__IOWRT;
  if ( !( flags & _O_TEXT ) ) flags |= _O_BINARY;

  fd = msvcrt_alloc_fd((HANDLE)hand,flags);
  TRACE(":handle (%ld) fd (%d) flags 0x%08x\n",hand,fd, flags);
*/
  /* MSVCRT__O_RDONLY (0) always matches, so set the read flag
   * MFC's CStdioFile clears O_RDONLY (0)! if it wants to write to the
   * file, so set the write flag. It also only sets MSVCRT__O_TEXT if it wants
   * text - it never sets MSVCRT__O_BINARY.
   */
  /* FIXME: handle more flags */
  /*
  LAG TEST SOM TESTER UT ALT DETTE flag tingern
  */
  if (!(oflags & (_O_BINARY | _O_TEXT)) && (_fmode & _O_BINARY))
      oflags |= _O_BINARY;
  else
      oflags |= _O_TEXT;

    return alloc_fd((HANDLE)osfhandle, split_oflags(oflags));
}

/*
 * @implemented
 */
long _get_osfhandle(int fd)
{
   TRACE("_get_osfhandle(%i)",fd);

    if (!is_valid_fd(fd)) {
        return( -1 );
    }
    return( (long)fdinfo(fd)->hFile );
}



/*
 * INTERNAL
 */
int __fileno_dup2(int handle1, int handle2)
{
   HANDLE hProcess;
   BOOL result;

   if (handle1 >= FDINFO_ENTRIES || handle1 < 0 || handle2 >= FDINFO_ENTRIES || handle2 < 0) {
      __set_errno(EBADF);
      return -1;
   }
//   if (_pioinfo[handle1]->fd == -1) {
   if (fdinfo(handle1)->hFile == INVALID_HANDLE_VALUE) {
      __set_errno(EBADF);
      return -1;
   }
   if (handle1 == handle2)
      return handle1;
//   if (_pioinfo[handle2]->fd != -1) {
   if (fdinfo(handle2)->hFile != INVALID_HANDLE_VALUE) {
      _close(handle2);
   }
   hProcess = GetCurrentProcess();
   result = DuplicateHandle(hProcess,
                fdinfo(handle1)->hFile,
                hProcess,
                &fdinfo(handle2)->hFile,
                0,
                fdinfo(handle1)->fdflags & FNOINHERIT ? FALSE : TRUE,
                DUPLICATE_SAME_ACCESS);
   if (result) {
//      _pioinfo[handle2]->fd = handle2;
      fdinfo(handle2)->fdflags = fdinfo(handle1)->fdflags;
      switch (handle2) {
      case 0:
         SetStdHandle(STD_INPUT_HANDLE, fdinfo(handle2)->hFile);
         break;
      case 1:
         SetStdHandle(STD_OUTPUT_HANDLE, fdinfo(handle2)->hFile);
         break;
      case 2:
         SetStdHandle(STD_ERROR_HANDLE, fdinfo(handle2)->hFile);
         break;
      }

      return handle1;
   } else {
      __set_errno(EMFILE);  // Is this the correct error no.?
      return -1;
   }
}


void* malloc(size_t sizeObject);



/*
 * INTERNAL
 */
BOOL __fileno_init(void)
{
  STARTUPINFOA  si;
  int           i;

  init_bucket(first_bucket);

  GetStartupInfoA(&si);

   if (si.cbReserved2 != 0 && si.lpReserved2 != NULL)
   {
    char*       fdflags_ptr;
    HANDLE*     handle_ptr;

    g_fdend = *(unsigned*)si.lpReserved2;

    fdflags_ptr= (char*)(si.lpReserved2 + sizeof(unsigned));
    handle_ptr = (HANDLE*)(fdflags_ptr + g_fdend * sizeof(char));

   g_fdend = min(g_fdend, FDINFO_ENTRIES);
   for (i = 0; i < g_fdend; i++)
   {
      if (!fdinfo_bucket(i))
      {
         if (!alloc_init_bucket(i)){
            /* FIXME: free other buckets? */
            return FALSE;
         }
      }

      if ((*fdflags_ptr & FOPEN) && *handle_ptr != INVALID_HANDLE_VALUE)
      {
        fdinfo(i)->fdflags  = *fdflags_ptr;
        fdinfo(i)->hFile = *handle_ptr;
      }
/*
      else
      {
        fdinfo(i)->fdflags  = 0;
        fdinfo(i)->hFile = INVALID_HANDLE_VALUE;
      }
*/
      fdflags_ptr++; handle_ptr++;
    }
    for (g_fdstart = 3; g_fdstart < g_fdend; g_fdstart++)
        if (fdinfo(g_fdstart)->hFile == INVALID_HANDLE_VALUE) break;
   }

   InitializeCriticalSection(&g_file_cs);


   if (fdinfo(0)->hFile == INVALID_HANDLE_VALUE || !(fdinfo(0)->fdflags & FOPEN)) {
      fdinfo(0)->hFile = GetStdHandle(STD_INPUT_HANDLE);
      if (fdinfo(0)->hFile == NULL)
         fdinfo(0)->hFile = INVALID_HANDLE_VALUE;
      fdinfo(0)->fdflags = FOPEN|FTEXT;
   }
   if (fdinfo(1)->hFile == INVALID_HANDLE_VALUE || !(fdinfo(1)->fdflags & FOPEN)) {
      fdinfo(1)->hFile = GetStdHandle(STD_OUTPUT_HANDLE);
      if (fdinfo(1)->hFile == NULL)
         fdinfo(1)->hFile = INVALID_HANDLE_VALUE;
      fdinfo(1)->fdflags = FOPEN|FTEXT;
   }
   if (fdinfo(2)->hFile == INVALID_HANDLE_VALUE || !(fdinfo(2)->fdflags & FOPEN)) {
      fdinfo(2)->hFile = GetStdHandle(STD_ERROR_HANDLE);
      if (fdinfo(2)->hFile == NULL)
         fdinfo(2)->hFile = INVALID_HANDLE_VALUE;
      fdinfo(2)->fdflags = FOPEN|FTEXT;
   }




   for (i = 0; i < 3; i++)
   {
      /* FILE structs for stdin/out/err are static and never deleted */
//      MSVCRT_fstreams[i] = &MSVCRT__iob[i];
   }
//   MSVCRT_stream_idx = 3;

   return TRUE;
}



/* INTERNAL: Create an inheritance data block (for spawned process)
 * The inheritance block is made of:
 *      00      int     nb of file descriptor (NBFD)
 *      04      char    file flags (wxflag): repeated for each fd
 *      4+NBFD  HANDLE  file handle: repeated for each fd
 */
unsigned create_io_inherit_block(STARTUPINFOA* si)
{
  int         fd;
  char*       fdflags_ptr;
  HANDLE*     handle_ptr;

  TRACE("create_io_inherit_block(%x)",si);

  si->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * g_fdend;
  si->lpReserved2 = calloc(si->cbReserved2, 1);
  if (!si->lpReserved2)
  {
    si->cbReserved2 = 0;
    return( FALSE );
  }
  fdflags_ptr = (char*)si->lpReserved2 + sizeof(unsigned);
  handle_ptr = (HANDLE*)(fdflags_ptr + g_fdend * sizeof(char));

  *(unsigned*)si->lpReserved2 = g_fdend;
  for (fd = 0; fd < g_fdend; fd++)
  {
    /* to be inherited, we need it to be open, and that DONTINHERIT isn't set */
    if ((fdinfo(fd)->fdflags & (FOPEN | FNOINHERIT)) == FOPEN)
    {
      *fdflags_ptr = fdinfo(fd)->fdflags;
      *handle_ptr = fdinfo(fd)->hFile;
    }
    else
    {
      *fdflags_ptr = 0;
      *handle_ptr = INVALID_HANDLE_VALUE;
    }
    fdflags_ptr++; handle_ptr++;
  }
  return( TRUE );
}




/*
 * @implemented
 */
int _setmode(int fd, int newmode)
{
   int prevmode;

   TRACE("_setmode(%d, %d)", fd, newmode);

   if (!is_valid_fd(fd))
   {
      DPRINT1("_setmode: inval fd (%d)\n",fd);
      //errno = EBADF;
      return(-1);
   }

   if (newmode & ~(_O_TEXT|_O_BINARY))
   {
      DPRINT1("_setmode: fd (%d) mode (0x%08x) unknown\n",fd,newmode);
      /* FIXME: Should we fail with EINVAL here? */
   }

   prevmode = fdinfo(fd)->fdflags & FTEXT ? _O_TEXT : _O_BINARY;

   if ((newmode & _O_TEXT) == _O_TEXT)
   {
      fdinfo(fd)->fdflags |= FTEXT;
   }
   else
   {
      /* FIXME: If both _O_TEXT and _O_BINARY are set, we get here.
       * Should we fail with EINVAL instead? -Gunnar
       */
      fdinfo(fd)->fdflags &= ~FTEXT;
   }

   return(prevmode);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -