-static struct GNUNET_DISK_FileHandle *
-npipe_create (char **fn, enum GNUNET_DISK_OpenFlags flags,
- enum GNUNET_DISK_AccessPermissions perm)
-{
- struct GNUNET_DISK_FileHandle *ret;
- HANDLE h = NULL;
- DWORD openMode;
- char *name;
-
- openMode = 0;
- if (flags & GNUNET_DISK_OPEN_READWRITE)
- openMode = PIPE_ACCESS_DUPLEX;
- else if (flags & GNUNET_DISK_OPEN_READ)
- openMode = PIPE_ACCESS_INBOUND;
- else if (flags & GNUNET_DISK_OPEN_WRITE)
- openMode = PIPE_ACCESS_OUTBOUND;
- if (flags & GNUNET_DISK_OPEN_FAILIFEXISTS)
- openMode |= FILE_FLAG_FIRST_PIPE_INSTANCE;
-
- while (NULL == h)
- {
- DWORD error_code;
-
- name = NULL;
- if (NULL != *fn)
- {
- GNUNET_asprintf (&name, "\\\\.\\pipe\\%.246s", fn);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Trying to create an instance of named pipe `%s'\n", name);
- /* 1) This might work just fine with UTF-8 strings as it is.
- * 2) This is only used by GNUnet itself, and only with latin names.
- */
- h = CreateNamedPipe (name, openMode | FILE_FLAG_OVERLAPPED,
- PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 2, 1, 1, 0,
- NULL);
- }
- else
- {
- GNUNET_asprintf (fn, "\\\\.\\pipe\\gnunet-%llu",
- GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
- UINT64_MAX));
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to create unique named pipe `%s'\n",
- *fn);
- h = CreateNamedPipe (*fn,
- openMode | FILE_FLAG_OVERLAPPED |
- FILE_FLAG_FIRST_PIPE_INSTANCE,
- PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 2, 1, 1, 0,
- NULL);
- }
- error_code = GetLastError ();
- GNUNET_free_non_null (name);
- /* don't re-set name to NULL yet */
- if (INVALID_HANDLE_VALUE == h)
- {
- SetErrnoFromWinError (error_code);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Pipe creation have failed because of %d, errno is %d\n", error_code,
- errno);
- if (NULL != *fn)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Pipe was to be unique, considering re-creation\n");
- GNUNET_free (*fn);
- *fn = NULL;
- if ( (ERROR_ACCESS_DENIED != error_code) && (ERROR_PIPE_BUSY != error_code) )
- return NULL;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Pipe name was not unique, trying again\n");
- h = NULL;
- }
- else
- return NULL;
- }
- }
- ret = GNUNET_malloc (sizeof (struct GNUNET_DISK_FileHandle));
- ret->h = h;
- ret->type = GNUNET_DISK_HANLDE_TYPE_PIPE;
- ret->oOverlapRead = GNUNET_malloc (sizeof (OVERLAPPED));
- ret->oOverlapWrite = GNUNET_malloc (sizeof (OVERLAPPED));
- ret->oOverlapRead->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
- ret->oOverlapWrite->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
- return ret;
-}
-