ReactOS  0.4.14-dev-384-g5b37caa
nbcmdqueue.c
Go to the documentation of this file.
1 /* Copyright (c) 2003 Juan Lang
2  *
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2.1 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  */
17 
18 #include "netapi32.h"
19 
21 
22 struct NBCmdQueue
23 {
27 };
28 
29 #define CANCEL_EVENT_PTR(ncb) (PHANDLE)((ncb)->ncb_reserve)
30 #define NEXT_PTR(ncb) (PNCB *)((ncb)->ncb_reserve + sizeof(HANDLE))
31 
32 /* The reserved area of an ncb will be used for the following data:
33  * - a cancelled flag (BOOL, 4 bytes??)
34  * - a handle to an event that's set by a cancelled command on completion
35  * (HANDLE, 4 bytes)
36  * These members are used in the following way
37  * - on cancel, set the event member of the reserved field (with create event)
38  * - NBCmdComplete will delete the ncb from the queue of there's no event;
39  * otherwise it will set the event and not delete the ncb
40  * - cancel must lock the queue before finding the ncb in it, and can unlock it
41  * once it's set the event (and the cancelled flag)
42  * - NBCmdComplete must lock the queue before attempting to remove the ncb or
43  * check the event
44  * - NBCmdQueueCancelAll will lock the queue, and cancel all ncb's in the queue.
45  * It'll then unlock the queue, and wait on the event in the head of the queue
46  * until there's no more ncb's in the queue.
47  * Space optimization: use the handle as a boolean. NULL == 0 => not cancelled.
48  * Non-NULL == valid handle => cancelled. This allows storing a next pointer
49  * in the ncb's reserved field as well, avoiding a memory alloc for a new
50  * command (cool).
51  */
52 
54 {
55  struct NBCmdQueue *queue;
56 
57  if (heap == NULL)
58  heap = GetProcessHeap();
59  queue = HeapAlloc(heap, 0, sizeof(struct NBCmdQueue));
60  if (queue)
61  {
62  queue->heap = heap;
64  queue->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": NBCmdQueue.cs");
65  queue->head = NULL;
66  }
67  return queue;
68 }
69 
71 {
72  UCHAR ret;
73 
74  TRACE(": queue %p, ncb %p\n", queue, ncb);
75 
76  if (!queue)
77  return NRC_BADDR;
78  if (!ncb)
79  return NRC_INVADDRESS;
80 
81  *CANCEL_EVENT_PTR(ncb) = NULL;
83  *NEXT_PTR(ncb) = queue->head;
84  queue->head = ncb;
85  ret = NRC_GOODRET;
87  TRACE("returning 0x%02x\n", ret);
88  return ret;
89 }
90 
92 {
93  PNCB *ret;
94 
95  if (!queue || !ncb)
96  ret = NULL;
97  else
98  {
99  ret = &queue->head;
100  while (ret && *ret != ncb)
101  ret = NEXT_PTR(*ret);
102  }
103  return ret;
104 }
105 
107 {
108  UCHAR ret;
109  PNCB *spot;
110 
111  TRACE(": queue %p, ncb %p\n", queue, ncb);
112 
113  if (!queue)
114  return NRC_BADDR;
115  if (!ncb)
116  return NRC_INVADDRESS;
117 
119  spot = NBCmdQueueFindNBC(queue, ncb);
120  if (spot)
121  {
124  CloseHandle(*CANCEL_EVENT_PTR(*spot));
125  *spot = *NEXT_PTR(*spot);
126  if (ncb->ncb_retcode == NRC_CMDCAN)
127  ret = NRC_CMDCAN;
128  else
129  ret = NRC_CANOCCR;
130  }
131  else
134  TRACE("returning 0x%02x\n", ret);
135  return ret;
136 }
137 
139 {
140  UCHAR ret;
141  PNCB *spot;
142 
143  TRACE(": queue %p, ncb %p\n", queue, ncb);
144 
145  if (!queue)
146  return NRC_BADDR;
147  if (!ncb)
148  return NRC_INVADDRESS;
149 
151  spot = NBCmdQueueFindNBC(queue, ncb);
152  if (spot)
153  {
154  if (*CANCEL_EVENT_PTR(*spot))
155  SetEvent(*CANCEL_EVENT_PTR(*spot));
156  else
157  *spot = *NEXT_PTR(*spot);
158  ret = NRC_GOODRET;
159  }
160  else
163  TRACE("returning 0x%02x\n", ret);
164  return ret;
165 }
166 
168 {
169  UCHAR ret;
170 
171  TRACE(": queue %p\n", queue);
172 
173  if (!queue)
174  return NRC_BADDR;
175 
177  while (queue->head)
178  {
179  TRACE(": waiting for ncb %p (command 0x%02x)\n", queue->head,
180  queue->head->ncb_command);
181  NBCmdQueueCancel(queue, queue->head);
182  }
184  ret = NRC_GOODRET;
185  TRACE("returning 0x%02x\n", ret);
186  return ret;
187 }
188 
190 {
191  TRACE(": queue %p\n", queue);
192 
193  if (queue)
194  {
196  queue->cs.DebugInfo->Spare[0] = 0;
198  HeapFree(queue->heap, 0, queue);
199  }
200 }
void NBCmdQueueDestroy(struct NBCmdQueue *queue)
Definition: nbcmdqueue.c:189
struct NBCmdQueue * NBCmdQueueCreate(HANDLE heap)
Definition: nbcmdqueue.c:53
#define CloseHandle
Definition: compat.h:406
#define NRC_GOODRET
Definition: nb30.h:52
#define DWORD_PTR
Definition: treelist.c:76
#define NRC_CANOCCR
Definition: nb30.h:77
UCHAR NBCmdQueueCancel(struct NBCmdQueue *queue, PNCB ncb)
Definition: nbcmdqueue.c:106
Definition: nb30.h:148
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
UCHAR NBCmdQueueComplete(struct NBCmdQueue *queue, PNCB ncb, UCHAR retcode)
Definition: nbcmdqueue.c:138
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define CANCEL_EVENT_PTR(ncb)
Definition: nbcmdqueue.c:29
#define NEXT_PTR(ncb)
Definition: nbcmdqueue.c:30
UCHAR NBCmdQueueCancelAll(struct NBCmdQueue *queue)
Definition: nbcmdqueue.c:167
Definition: _queue.h:59
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
smooth NULL
Definition: ftsmooth.c:416
PNCB head
Definition: nbcmdqueue.c:26
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define NRC_CMDCAN
Definition: nb30.h:61
HANDLE heap
Definition: nbcmdqueue.c:24
unsigned char UCHAR
Definition: xmlstorage.h:181
WINE_DEFAULT_DEBUG_CHANNEL(netbios)
int ret
CRITICAL_SECTION cs
Definition: nbcmdqueue.c:25
#define NRC_BADDR
Definition: nb30.h:57
static PNCB * NBCmdQueueFindNBC(struct NBCmdQueue *queue, PNCB ncb)
Definition: nbcmdqueue.c:91
#define NRC_INVADDRESS
Definition: nb30.h:85
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define INFINITE
Definition: serial.h:102
#define HeapFree(x, y, z)
Definition: compat.h:402
UCHAR NBCmdQueueAdd(struct NBCmdQueue *queue, PNCB ncb)
Definition: nbcmdqueue.c:70
UCHAR ncb_retcode
Definition: nb30.h:150