HRESULT CActiveRequestPool::Remove()
{
	HRESULT hr;
	BOOL signal = FALSE;

	ENTER_CS(this->syncRoot)

	ErrorIf(this->requestCount == 0, ERROR_INVALID_OPERATION);

	this->requestCount--;

	if (NULL != this->drainHandle && 0 == this->requestCount)
	{
		signal = TRUE;
	}

	LEAVE_CS(this->syncRoot)

	if (signal)
	{
		SetEvent(this->drainHandle);
	}

	return S_OK;
Error:
	return hr;
}
HRESULT CActiveRequestPool::Remove(CNodeHttpStoredContext* context)
{
	HRESULT hr;
	BOOL signal = FALSE;

	CheckNull(context);

	ENTER_CS(this->syncRoot)

	this->requests.remove(context);

	if (NULL != this->drainHandle && this->requests.empty())
	{
		signal = TRUE;
	}

	LEAVE_CS(this->syncRoot)

	if (signal)
	{
		SetEvent(this->drainHandle);
	}

	return S_OK;
Error:
	return hr;
}
Exemple #3
0
HRESULT CFileWatcher::RemoveWatch(CNodeApplication* application)
{
	ENTER_CS(this->syncRoot)

	WatchedDirectory* directory = this->directories;
	WatchedDirectory* previousDirectory = NULL;
	while (directory)
	{
		WatchedFile* file = directory->files;
		WatchedFile* previousFile = NULL;
		while (file && file->application != application)
		{
			previousFile = file;
			file = file->next;
		}

		if (file)
		{
			delete [] file->fileName;
			if (previousFile)
			{
				previousFile->next = file->next;
			}
			else
			{
				directory->files = file->next;
			}

			delete file;

			if (!directory->files)
			{
				delete [] directory->directoryName;
				CloseHandle(directory->watchHandle);

				if (previousDirectory)
				{
					previousDirectory->next = directory->next;
				}
				else
				{
					this->directories = directory->next;
				}

				delete directory;
			}

			break;
		}

		previousDirectory = directory;
		directory = directory->next;
	}

	LEAVE_CS(this->syncRoot)

	return S_OK;
}
static void SNP_sendAsyncCmd(_npiFrame_t *pPkt)
{
  // Enter Critical Section.
  ENTER_CS();

  // Send command.
  SEND_MESSAGE(pPkt);

  // Exit Critical section
  EXIT_CS();
}
HRESULT CActiveRequestPool::Add(CNodeHttpStoredContext* context)
{
	HRESULT hr;

	CheckNull(context);

	ENTER_CS(this->syncRoot)

	ErrorIf(this->requests.size() >= CModuleConfiguration::GetMaxConcurrentRequestsPerProcess(context->GetHttpContext()), ERROR_NOT_ENOUGH_QUOTA);
	this->requests.push_back(context);

	LEAVE_CS(this->syncRoot)

	return S_OK;
Error:
	return hr;
}
HRESULT CPendingRequestQueue::Push(CNodeHttpStoredContext* context)
{
	HRESULT hr;

	CheckNull(context);

	ENTER_CS(this->syncRoot)

	ErrorIf(this->requests.size() >= CModuleConfiguration::GetMaxPendingRequestsPerApplication(context->GetHttpContext()), ERROR_NOT_ENOUGH_QUOTA);
	this->requests.push(context);

	LEAVE_CS(this->syncRoot)

	return S_OK;
Error:
	return hr;
}
HRESULT CNodeApplicationManager::Dispatch(IHttpContext* context, IHttpEventProvider* pProvider, CNodeHttpStoredContext** ctx)
{
	HRESULT hr;
	CNodeApplication* application;
	NodeDebugCommand debugCommand;

	CheckNull(ctx);
	*ctx = NULL;

	CheckError(CNodeDebugger::GetDebugCommand(context, this->GetEventProvider(), &debugCommand));

	if (ND_KILL == debugCommand)
	{
		ENTER_CS(this->syncRoot)

		CheckError(this->EnsureDebuggedApplicationKilled(context, ctx));

		LEAVE_CS(this->syncRoot)
	}
static void SNP_sendSynchronousCmd(_npiFrame_t *pReq, uint8_t opcode,
                                   snp_msg_t *pRsp, uint16_t *rspLen)
{
  // Enter Critical Section.
  ENTER_CS();

  npiRetMsg.pMsg = pRsp;

  // Send command.
  SEND_MESSAGE(pReq);

  // Wait for a response from the NP.
  SNP_waitForResponse();

  // Update Length after response is received
  if (rspLen)
  {
    *rspLen = npiRetMsg.len;
  }

  // Exit Critical Section
  EXIT_CS();
}
Exemple #9
0
HRESULT CFileWatcher::WatchFiles(PCWSTR mainFileName, PCWSTR watchedFiles, FileModifiedCallback callback, CNodeApplicationManager* manager, CNodeApplication* application)
{
	HRESULT hr;
	WCHAR fileOnly[_MAX_FNAME];
	WCHAR ext[_MAX_EXT];
	WCHAR* directoryName = NULL;
	DWORD fileNameLength;
	DWORD fileNameOnlyLength;
	DWORD directoryLength;	
	BOOL unc;
	BOOL wildcard;
	PWSTR startSubdirectory;
	PWSTR startFile;
	PWSTR endFile;
	WatchedDirectory* directory;
	WatchedFile* file;

	CheckNull(mainFileName);
	CheckNull(watchedFiles);

	// create and normalize a copy of directory name, determine if it is UNC share

	fileNameLength = wcslen(mainFileName);
	ErrorIf(0 != _wsplitpath_s(mainFileName, NULL, 0, NULL, 0, fileOnly, _MAX_FNAME, ext, _MAX_EXT), ERROR_INVALID_PARAMETER);	
	fileNameOnlyLength = wcslen(fileOnly) + wcslen(ext);	
	directoryLength = fileNameLength - fileNameOnlyLength; 
	ErrorIf(NULL == (directoryName = new WCHAR[directoryLength + 8]), ERROR_NOT_ENOUGH_MEMORY); // pessimistic length after normalization with prefix \\?\UNC\ 

	if (fileNameLength > 8 && 0 == memcmp(mainFileName, L"\\\\?\\UNC\\", 8 * sizeof WCHAR))
	{
		// normalized UNC path
		unc = TRUE;
		memcpy(directoryName, mainFileName, directoryLength * sizeof WCHAR);
		directoryName[directoryLength] = L'\0';
	}
	else if (fileNameLength > 4 && 0 == memcmp(mainFileName, L"\\\\?\\", 4 * sizeof WCHAR))
	{
		// normalized local file
		unc = FALSE;
		memcpy(directoryName, mainFileName, directoryLength * sizeof WCHAR);
		directoryName[directoryLength] = L'\0';
	}
	else if (fileNameLength > 2 && 0 == memcmp(mainFileName, L"\\\\", 2 * sizeof(WCHAR)))
	{
		// not normalized UNC path
		unc = TRUE;
		wcscpy(directoryName, L"\\\\?\\UNC\\");
		memcpy(directoryName + 8, mainFileName + 2, (directoryLength - 2) * sizeof WCHAR);
		directoryName[8 + directoryLength - 2] = L'\0';
	}
	else
	{
		// not normalized local file
		unc = FALSE;
		wcscpy(directoryName, L"\\\\?\\");
		memcpy(directoryName + 4, mainFileName, directoryLength * sizeof WCHAR);
		directoryName[4 + directoryLength] = L'\0';	
	}

	directoryLength = wcslen(directoryName);

	ENTER_CS(this->syncRoot)

	// parse watchedFiles and create a file listener for each of the files

	startFile = (PWSTR)watchedFiles;
	do {
		endFile = startSubdirectory = startFile;
		wildcard = FALSE;
		while (*endFile && *endFile != L';')
		{
			wildcard |= *endFile == L'*' || *endFile == L'?';
			if (*endFile == L'\\')
			{
				startFile = endFile + 1;
			}

			endFile++;
		}

		if (startFile != endFile)
		{
			hr = this->WatchFile(directoryName, directoryLength, unc, startSubdirectory, startFile, endFile, wildcard);

			// ignore files and directories that do not exist instead of failing

			if (S_OK != hr && ERROR_FILE_NOT_FOUND != hr)
			{
				// still under lock remove file watch entries that were just created, then do regular cleanup

				this->RemoveWatch(NULL);
				CheckError(hr);
			}
		}

		startFile = endFile + 1;

	} while(*endFile);

	// update temporary entries with application and callback pointers

	directory = this->directories;
	while (NULL != directory)
	{
		file = directory->files;
		while (NULL != file)
		{
			if (NULL == file->application)
			{
				file->application = application;
				file->manager = manager;
				file->callback = callback;
			}

			file = file->next;
		}

		directory = directory->next;
	}

	LEAVE_CS(this->syncRoot)

	delete [] directoryName;

	return S_OK;

Error:

	if (NULL != directoryName)
	{
		delete [] directoryName;
		directoryName = NULL;
	}


	return hr;
}
Exemple #10
0
unsigned int CFileWatcher::Worker(void* arg)
{
	CFileWatcher* watcher = (CFileWatcher*)arg;
	DWORD error;
	DWORD bytes;
	ULONG_PTR key;
	LPOVERLAPPED overlapped;

	while (TRUE)
	{
		error = S_OK;
		if (!GetQueuedCompletionStatus(
			watcher->completionPort, &bytes, &key, &overlapped, watcher->uncFileSharePollingInterval))
		{
			error = GetLastError();
		}

		if (-1L == key) // terminate thread
		{
			break;
		}
		else if (S_OK == error) // a change in registered directory detected (local file system)
		{
			WatchedDirectory* directory = (WatchedDirectory*)key;
			
			ENTER_CS(watcher->syncRoot)

			// make sure the directory is still watched

			WatchedDirectory* current = watcher->directories;
			while (current && current != directory)
				current = current->next;

			if (current)
			{
				watcher->ScanDirectory(current, FALSE);

				// make sure the directory is still watched - it could have been removed by a recursive call to RemoveWatch

				current = watcher->directories;
				while (current && current != directory)
					current = current->next;

				if (current)
				{
					RtlZeroMemory(&current->overlapped, sizeof current->overlapped);
					ReadDirectoryChangesW(
						current->watchHandle,
						&current->info,
						sizeof directory->info,
						FALSE,
						FILE_NOTIFY_CHANGE_LAST_WRITE,
						NULL,
						&current->overlapped,
						NULL);
				}
			}

			LEAVE_CS(watcher->syncRoot)
		}
		else // timeout - scan all registered UNC files for changes
		{
Exemple #11
0
HRESULT CFileWatcher::RemoveWatch(CNodeApplication* application)
{
	ENTER_CS(this->syncRoot)

	WatchedDirectory* directory = this->directories;
	WatchedDirectory* previousDirectory = NULL;
	while (directory)
	{
		WatchedFile* file = directory->files;
		WatchedFile* previousFile = NULL;

		while (file)
		{
			if (file->application == application)
			{
				WatchedFile* tmpFile = file;
				delete [] file->fileName;
				if (previousFile)
				{
					previousFile->next = file->next;
					file = file->next;
					if (!file)
					{
						previousDirectory = directory;
						directory = directory->next;
					}
				}
				else
				{
					directory->files = file->next;
					file = file->next;
					if (!directory->files)
					{
						delete [] directory->directoryName;
						if(directory->watchHandle != NULL)
						{
							CloseHandle(directory->watchHandle);
							directory->watchHandle = NULL;
						}

						if (previousDirectory)
						{
							previousDirectory->next = directory->next;
						}
						else
						{
							this->directories = directory->next;
						}

						WatchedDirectory* tmpDirectory = directory;
						directory = directory->next;
						delete tmpDirectory;
					}
				}

				delete tmpFile;
			}
			else
			{
				previousFile = file;
				file = file->next;
				if (!file)
				{
					previousDirectory = directory;
					directory = directory->next;
				}
			}
		}
	}

	LEAVE_CS(this->syncRoot)

	return S_OK;
}