コード例 #1
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
/* userlist_user_gender:
 *	returns user's gender
 */
enum vqp_gender userlist_user_gender(const char * user_name)
{
	struct userlist_entry * entry;
	ASSERT_RETURNVALIFFAIL(VALIDPTR(user_name) && VALIDPTR(s_userlistHash), 0);
	entry = userlist_entry_by_name(user_name);
	return entry ? entry->gender: VQP_GENDER_MALE;
}
コード例 #2
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
/* userlist_remove:
 *	removes specified user from userlist
 * params:
 *	@explicit_part - non-0 if the user left explicitly (he notified us of that)
 */
void userlist_remove(const char * user_name, int explicit_remove)
{
	struct userlist_entry * entry;

	ASSERT_RETURNIFFAIL(VALIDPTR(user_name) && VALIDPTR(s_userlistHash));

	entry = userlist_entry_by_name(user_name);
	if(entry) {
		const char * enum_cb_data[2];
		
		/* notify DB that the user has become offline
		 * (if the user is in db list)
		 */
		HANDLE hContact = contacts_find_contact(user_name);
		if(hContact)
			contacts_set_contact_status(hContact, ID_STATUS_OFFLINE);

		/* update user's chatroom:
		 * leave every channel the user is in */
		enum_cb_data[0] = user_name;
		enum_cb_data[1] = (const char *)explicit_remove;
		chanlist_enum(
			entry->chanlist,
			userlist_remove_channel_part_enum, (void*)enum_cb_data);
		
		/* remove user entry from the hash and free it */
		hashtable_remove(s_userlistHash, (void*)user_name, 1);
	}
}
コード例 #3
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
/* userlist_user_swversion:
 *	returns' user's software version
 */
unsigned int userlist_user_swversion(const char * user_name)
{
	struct userlist_entry * entry;
	ASSERT_RETURNVALIFFAIL(VALIDPTR(user_name) && VALIDPTR(s_userlistHash), 0);
	entry = userlist_entry_by_name(user_name);
	return entry ? entry->swversion: VQCHAT_UNDEF_SWVERSION;
}
コード例 #4
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
/* userlist_user_is_chat_open:
 *	returns if we have a private chat opened with the user
 */
int userlist_user_is_chat_open(const char * user_name)
{
	struct userlist_entry * entry;
	ASSERT_RETURNVALIFFAIL(VALIDPTR(user_name) && VALIDPTR(s_userlistHash), 0);
	entry = userlist_entry_by_name(user_name);
	return entry ? entry->chat_open: 0;
}
コード例 #5
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
void userlist_user_chanlist_update(
	const char * user_name,
	const char * updated_chanlist)
{
	struct userlist_entry * entry;

	ASSERT_RETURNIFFAIL(VALIDPTR(user_name) && VALIDPTR(s_userlistHash));
	entry = userlist_entry_by_name(user_name);
	if(entry) {
		const char * enum_fn_data[2];
		char * new_chanlist = chanlist_copy(updated_chanlist);

		/* join new previously-missing channels */
		chanlist_enum(
			new_chanlist,
			userlist_user_chanlist_update_join_enum_fn, (void*)user_name);

		/* leave the channels that the user is off */
		enum_fn_data[0] = new_chanlist;
		enum_fn_data[1] = user_name;
		chanlist_enum(
			entry->chanlist,
			userlist_user_chanlist_update_part_enum_fn, (void*)enum_fn_data);

		/* free chanlists */
		chanlist_free(new_chanlist);
	}
}
コード例 #6
0
ファイル: FileCapture.cpp プロジェクト: SEC-squad/core-win64
BOOL H_DeleteFileW_setup(H_DeleteFileWStruct *data)
{
    HMODULE hMod;
    VALIDPTR(hMod = GetModuleHandle("KERNEL32.DLL"))
    VALIDPTR(data->pGetCurrentProcessId = (GetCurrentProcessId_t)GetProcAddress(hMod, "GetCurrentProcessId"))
    return TRUE;
}
コード例 #7
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
/* userlist_user_set_chat_open:
 *	sets wherether the chat is open with the user
 */
void userlist_user_set_chat_open(const char * user_name, int set_chat_open)
{
	struct userlist_entry * entry;
	ASSERT_RETURNIFFAIL(VALIDPTR(user_name) && VALIDPTR(s_userlistHash));

	entry = userlist_entry_by_name(user_name);
	if(entry)
		entry->chat_open = set_chat_open;
}
コード例 #8
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
/* userlist_user_status:
 *	returns miranda's status for user, or ID_STATUS_OFFLINE, if not found
 */
int userlist_user_status(const char * user_name)
{
	struct userlist_entry * entry;

	ASSERT_RETURNVALIFFAIL(VALIDPTR(user_name) && VALIDPTR(s_userlistHash), ID_STATUS_OFFLINE);

	entry = userlist_entry_by_name(user_name);
	return entry ? user_status_by_vqp_status(entry->vqp_status): ID_STATUS_OFFLINE;
}
コード例 #9
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
/* userlist_user_chanlist:
 *	returns users' chanlist
 */
const char *
userlist_user_chanlist(const char * user_name)
{
	struct userlist_entry * entry;
	ASSERT_RETURNVALIFFAIL(VALIDPTR(user_name) && VALIDPTR(s_userlistHash), 0);

	entry = userlist_entry_by_name(user_name);
	return entry ? entry->chanlist: NULL;

}
コード例 #10
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
static int userlist_remove_channel_part_enum(
	const char * channel, void * enum_data)
{
	const char * user = ((const char **)enum_data)[0],
	      * explicit_part = ((const char **)enum_data)[1];

	ASSERT_RETURNVALIFFAIL(VALIDPTR(channel) && VALIDPTR(enum_data), 0);

	userlist_user_channel_part(user, channel, (int)explicit_part);
	return 1;
}
コード例 #11
0
ファイル: chanlist.c プロジェクト: 0xmono/miranda-ng
/* chanlist_merge:
 *	  Merges two chanlists, the result adds to chanlist_dst
 *	and it is what returns.
 *
 *	  Note that chanlist_src might get modified in the process
 *	thus it is non-const, but it is kept unmodified after return.
 */
static int
chanlist_merge_enum_fn(const char * channel, void * enum_data)
{
	char ** p_dst_chanlist = (char **)enum_data;

	ASSERT_RETURNVALIFFAIL(VALIDPTR(channel), 0);
	ASSERT_RETURNVALIFFAIL(VALIDPTR(p_dst_chanlist), 0);

	*p_dst_chanlist = chanlist_add(*p_dst_chanlist, channel);

	return 1;	/* keep enumerating */
}
コード例 #12
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
/* userlist_add:
 *	adds user to userlist, updates it's info if the user already exists
 */
void userlist_add(
	const char * name,
	enum vqp_status vqp_status, enum vqp_gender gender, const vqp_uuid_t * p_uuid,
	enum vqp_codepage codepage, unsigned int swversion, vqp_addr_t addr,
	int add_to_log)
{
	struct userlist_entry * entry;
	HANDLE hContact;

	ASSERT_RETURNIFFAIL(VALIDPTR(name) && VALIDPTR(s_userlistHash));

	entry = userlist_entry_by_name(name);
	if(entry) {
		entry->alive = 1;

		userlist_entry_status_change(
			name, entry, vqp_status, gender, "", add_to_log);
		return;
	}

	/* setup new user list entry struct */
	entry = malloc(sizeof(struct userlist_entry));
	entry->vqp_status = vqp_status;
	entry->codepage = codepage;
	entry->gender = gender;
	entry->swversion = swversion;
	entry->uuid = *p_uuid;
	entry->addr = addr;
	entry->alive = 1;
	entry->chat_open = 0;
	entry->chanlist = NULL;

	/* insert into the hash table */
	hashtable_insert(s_userlistHash, strdup(name), entry);

	/* notify DB that the user has become visible (if he is on list)
	 * and set user ip
	 */
	hContact = contacts_find_contact(name);
	if(hContact) {
		contacts_set_contact_status(hContact, user_status_by_vqp_status(vqp_status));
		contacts_set_contact_addr(hContact, addr);
	}

	/* every user of QuickChat/VypressChat networks is a member
	 * of #Main channel */
	userlist_user_channel_join(name, VQCHAT_MAIN_CHANNEL, add_to_log);
}
コード例 #13
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
void userlist_user_channel_join(
	const char * user_name, const char * channel,
	int add_to_log)
{
	struct userlist_entry * entry;
	ASSERT_RETURNIFFAIL(VALIDPTR(user_name) && VALIDPTR(s_userlistHash));

	entry = userlist_entry_by_name(user_name);
	if(entry && !chanlist_contains(entry->chanlist, channel)) {
		/* add channel to user's channel list */
		entry->chanlist = chanlist_add(entry->chanlist, channel);

		/* notify chatrooms */
		chatroom_channel_user_join(channel, user_name, add_to_log);
	}
}
コード例 #14
0
ファイル: chanlist.c プロジェクト: 0xmono/miranda-ng
/* chanlist_shift:
 *	removes the first channel from the list and returns
 *	the chanlist without the channel
 *
 * params:
 *	@p_chanlist - chanlist to shift the channel off
 * returns:
 *	NULL, if the chanlist is empty
 *	malloc'ed channel name shifted from the chanlist
 */
char * chanlist_shift(char ** p_chanlist)
{
	char * next, * new_chanlist, * channel;
	
	/* check that the channel is valid */
	ASSERT_RETURNVALIFFAIL(VALIDPTR(p_chanlist), NULL);
	if(!chanlist_is_valid(*p_chanlist, 0))
		return NULL;

	/* check if chanlist is empty */
	if(*p_chanlist==NULL) return NULL;

	/* get pointer to the next channel in the list */
	next = strchr(*p_chanlist + 1, '#');

	/* make a copy of the rest as new chanlist */
	new_chanlist = chanlist_copy(next);
	
	/* finish channel name with a '\0' */
	if(next) *next = '\0';
	channel = *p_chanlist;
	memmove(channel, channel + 1, strlen(channel));

	*p_chanlist = new_chanlist;
	return channel;
}
コード例 #15
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
static void CALLBACK
userlist_remove_unreplied_cb(
	HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
	struct userlist_remove_unreplied_info_struct info;
	int i;
	char * r_nickname;
	
	ASSERT_RETURNIFFAIL(VALIDPTR(s_userlistHash));

	/* perform enumeration to find the unreplied ones */
	info.dead_keys = malloc(
			sizeof(void*) * hashtable_count(s_userlistHash));
	info.dead_key_count = 0;
	hashtable_enumerate(
		s_userlistHash,
		userlist_remove_unreplied_enum_fn, (void*)&info);

	/* quietly remove those dead */
	for(i = 0; i < info.dead_key_count; i++) {
		userlist_remove(info.dead_keys[i], 0);
		free(info.dead_keys[i]);
	}

	/* free leftovers */
	free(info.dead_keys);

	/* send another user refresh list request to the network
	 */
	r_nickname = util_utf2vqp(user_codepage(), user_nickname());
	msgloop_send(vqp_msg_refresh_req(s_vqpLink, r_nickname, user_codepage()), 0);
	free(r_nickname);
}
コード例 #16
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
void userlist_status_change(
	const char * user_name,
	enum vqp_status new_user_status, enum vqp_gender new_user_gender,
	const char * status_text, int add_to_log)
{
	struct userlist_entry * entry;

	ASSERT_RETURNIFFAIL(VALIDPTR(user_name) && VALIDPTR(s_userlistHash));

	entry = userlist_entry_by_name(user_name);
	if(entry) {
		userlist_entry_status_change(
			user_name, entry, new_user_status, new_user_gender,
			status_text, add_to_log);
	}
}
コード例 #17
0
ファイル: os2fake-win.c プロジェクト: egraba/kbuild_openbsd
APIRET OS2ENTRY         DosFindNext(
                            HDIR        hDir,
                            PVOID       pFindBuf,
                            ULONG       cbFindBuf,
                            PULONG      pcFileNames)
{
    WIN32_FIND_DATA FindData;           /* Win32 Find data (returned by FindFirstFile) */
    APIRET          rc;

    if (!VALIDPTR(pFindBuf))
    {
        fprintf(stderr, "DosFindNext: pfindbuf - %p\n", pFindBuf);
        return ERROR_INVALID_PARAMETER;
    }

    if (cbFindBuf < sizeof(FILEFINDBUF3))
    {
        fprintf(stderr, "DosFindNext: unsupported buffer size - %d\n", cbFindBuf);
        return ERROR_INVALID_PARAMETER;
    }

    if (!VALIDPTR(pcFileNames))
    {
        fprintf(stderr, "DosFindNext: pcFileNames - %p\n", pcFileNames);
        return ERROR_INVALID_PARAMETER;
    }

    if (FindNextFile((HANDLE)hDir, &FindData))
    {
        PFILEFINDBUF3   pfindbuf = (PFILEFINDBUF3)pFindBuf;

        memcpy(pfindbuf->achName, FindData.cFileName, pfindbuf->cchName = strlen(FindData.cFileName) + 1);
        pfindbuf->cbFile = pfindbuf->cbFileAlloc = FindData.nFileSizeHigh > 0 ? 0xffffffff : FindData.nFileSizeLow;
        pfindbuf->attrFile = ConvertAttributes(FindData.dwFileAttributes);
        *(PULONG)(&pfindbuf->fdateCreation) = ConvertFileTime(&FindData.ftCreationTime);
        *(PULONG)(&pfindbuf->fdateLastAccess) = ConvertFileTime(&FindData.ftLastAccessTime);
        *(PULONG)(&pfindbuf->fdateLastWrite) = ConvertFileTime(&FindData.ftLastWriteTime);
        pfindbuf->oNextEntryOffset = 0;
        *pcFileNames = 1;
        rc = NO_ERROR;
    }
    else
        rc = GetLastError();

    return rc;

}
コード例 #18
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
/* userlist_user_codepage_vqp:
 *	tries to get or guess codepage for specified user name
 *	(on vypresschat it tries UTF8 encoding first, on qChat - locale)
 */
enum vqp_codepage
userlist_user_codepage_vqp(const char * vqp_user_name)
{
	struct userlist_entry * entry;
	ASSERT_RETURNVALIFFAIL(VALIDPTR(vqp_user_name), VQCHAT_VQP_COMPAT_CODEPAGE);

	entry = userlist_entry_by_name_vqp(vqp_user_name);
	return entry ? entry->codepage: VQCHAT_VQP_COMPAT_CODEPAGE;
}
コード例 #19
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
void userlist_user_set_codepage(const char * user_name, enum vqp_codepage codepage)
{
	struct userlist_entry * entry;
	ASSERT_RETURNIFFAIL(VALIDPTR(user_name));

	entry = userlist_entry_by_name(user_name);
	if(entry)
		entry->codepage = codepage;
}
コード例 #20
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
/* userlist_user_channel_part:
 *	this will make the user leave the specified channel
 * parameters:
 *	@explicit_part - specifies whether the user left explicitly, or because
 *	of refresh timeout
 */
void userlist_user_channel_part(
	const char * user_name, const char * channel,
	int explicit_part)
{
	struct userlist_entry * entry;

	ASSERT_RETURNIFFAIL(VALIDPTR(user_name) && VALIDPTR(s_userlistHash));
	ASSERT_RETURNIFFAIL(VALIDPTR(channel));

	entry = userlist_entry_by_name(user_name);
	if(entry && chanlist_contains(entry->chanlist, channel)) {
		/* remove channel from user's channel list */
		entry->chanlist = chanlist_remove(entry->chanlist, channel);

		/* notify chatrooms */
		chatroom_channel_user_part(channel, user_name, explicit_part);
	}
}
コード例 #21
0
ファイル: chanlist.c プロジェクト: 0xmono/miranda-ng
/* chanlist_add:
 *	  Creates a channel list (if chanlist==NULL) with a new channel
 *	or add a new one to the end.
 *	  Checks if the channel is already in the list.
 * 	  The result channel list string should look like:
 *		"#channel1#channel2...#channelN".
 *	  An empty channel list is a (char*)NULL.
 */
char * chanlist_add(char * chanlist, const char * channel)
{
	char * new_chanlist;
	int cl_len, ch_len;

	ASSERT_RETURNVALIFFAIL(VALIDPTR(channel), chanlist);

	if(chanlist_find_channel(chanlist, channel, NULL, NULL))
		return chanlist;

	/* the chanlist doesn't contain the new channel:
	 * append it to the end
	 */

	ch_len = strlen(channel);
	ASSERT_RETURNVALIFFAIL(ch_len!=0, chanlist);

	if(chanlist) {
		/* get the length of channel list, note that an empty chanlist
		 * MUST be (char*)NULL, and an non-empty chanlist must be at
		 * least 2 chars in length ("#a") and have '#' at the beginning
		 */
		cl_len = strlen(chanlist);
		ASSERT_RETURNVALIFFAIL(
			cl_len >= 2 && chanlist[0]=='#', chanlist);
	} else {
		cl_len = 0;
	}

	/* allocate space for a previous channel list, plus a # character
	 * and new channel, and a terminator
	 */
	new_chanlist = malloc((cl_len + ch_len + 1 + 1) * sizeof(char));
	ASSERT_RETURNVALIFFAIL(new_chanlist!=NULL, chanlist);

	if(chanlist) {
		/* strcpy(new_chanlist, chanlist); */
		memcpy(new_chanlist, chanlist, cl_len);
		free(chanlist);
	}

	new_chanlist[cl_len] = '#';	/* strcat(new_chanlist, "#"); */

	/* strcat(new_chanlist, channel); */
	memcpy(new_chanlist + cl_len + 1, channel, ch_len + 1); 

	return new_chanlist;
}
コード例 #22
0
ファイル: chanlist.c プロジェクト: 0xmono/miranda-ng
/* chanlist_make_vqp_chanlist:
 *	allocates a vqp chanlist (the same as chanlist, only with '#' at the end)
 *	and always non-NULL
 */
char * chanlist_make_vqp_chanlist(const char * chanlist)
{
	int cl_len;
	char * vqp_chanlist;

	cl_len = chanlist ? strlen(chanlist): 0;
	
	vqp_chanlist = malloc(cl_len + 2);
	ASSERT_RETURNVALIFFAIL(VALIDPTR(vqp_chanlist), NULL);

	if(chanlist)
		memcpy(vqp_chanlist, chanlist, cl_len);

	/* append the '#' and '\0' terminator at the end */
	vqp_chanlist[cl_len] = '#';
	vqp_chanlist[cl_len + 1] = '\0';

	return vqp_chanlist;
}
コード例 #23
0
ファイル: chanlist.c プロジェクト: 0xmono/miranda-ng
/* chanlist_parse_vqp_chanlist:
 *	makes a chanlist from vqp chanlist format
 */
char * chanlist_parse_vqp_chanlist(const char * vqp_chanlist)
{
	int vqp_cl_len;
	char * chanlist;
	
	ASSERT_RETURNVALIFFAIL(VALIDPTR(vqp_chanlist), NULL);

	vqp_cl_len = strlen(vqp_chanlist);
	ASSERT_RETURNVALIFFAIL(vqp_cl_len != 0, NULL);

	/* vqp_chanlist must begin and end with '#' */
	ASSERT_RETURNVALIFFAIL(
		vqp_chanlist[0]=='#' && vqp_chanlist[vqp_cl_len-1]=='#', NULL);

	/* make the chanlist (copy everything, except the last '#') */
	chanlist = malloc(vqp_cl_len);
	memcpy(chanlist, vqp_chanlist, vqp_cl_len - 1);
	chanlist[vqp_cl_len - 1] ='\0';

	return chanlist;
}
コード例 #24
0
ファイル: msgloop.c プロジェクト: 0xmono/miranda-ng
/* msgloop_send:
 *	msgloop_send should be used to send a message from miranda's
 *	gui thread to send a message with qcs_msg loop.
 */
void msgloop_send(vqp_msg_t msg, int never_wait)
{
	ASSERT_RETURNIFFAIL(VALIDPTR(msg));

	/* send this message */
	if(s_fLoopStarted && s_outputTimer) {
		/* check if we've sent a packet this tick,
		 * and if we did, we'll have to wait for the next tick
		 */
		if(s_outputSentThisTick && !never_wait) {
			/* add msg to message queue for scheduler timer
			 */
			struct msgloop_message_list_entry * entry;
			entry = malloc(sizeof(struct msgloop_message_list_entry));
			entry->msg = msg;
			entry->next = NULL;
			entry->prev = s_outputListHead;
			if(entry->prev) {
				entry->prev->next = entry;
			} else {
				s_outputListTail = entry;
			}
			s_outputListHead = entry;
		} else {
			QueueUserAPC(msgloop_apc_send_msg, s_hLoopThread, (ULONG_PTR)msg);
			s_outputSentThisTick = TRUE;
		}
	} else {
		if(s_outputSentThisTick && !never_wait) {
			Sleep(PACKET_OUTPUT_RATE);
		}
		vqp_link_send(msg);
		vqp_msg_free(msg);
		s_outputSentThisTick = TRUE;
		s_outputSentThisTickInTimer = FALSE;
	}
}
コード例 #25
0
ファイル: chanlist.c プロジェクト: 0xmono/miranda-ng
/* chanlist_remove:
 *	  Removes a channel from chanlist and frees the resulting
 *	chanlist, if it becomes empty (thus returning the (char*)NULL)
 */
char * chanlist_remove(char * chanlist, const char * channel)
{
	char * cl_channel;
	int cl_len, ch_len;

	ASSERT_RETURNVALIFFAIL(VALIDPTR(channel), chanlist);

	if(chanlist==NULL)
		return NULL;

	cl_channel = (char*)chanlist_find_channel(
				chanlist, channel, &cl_len, &ch_len);

	if(cl_channel == NULL)
		return chanlist;

	/* check if we need to free the list, (if it was the only channel) */
	if(cl_len == ch_len + 1) {
		free(chanlist);
		return NULL;
	}

	/* if the channel was the last on the list, we put a terminator '\0'
	 * and we're finished */
	if((cl_channel - chanlist) + ch_len == cl_len) {
		*(cl_channel - 1) = '\0'; /* put '\0' on channel's '#' char */
		return chanlist;
	}

	/* we need to move channels after cl_channel in the chanlist
	 * to the place of cl_channel (including the '\0' terminator) */
	memcpy(cl_channel, cl_channel + ch_len + 1,
		cl_len - (cl_channel - chanlist) - ch_len);

	return chanlist;
}
コード例 #26
0
ファイル: chanlist.c プロジェクト: 0xmono/miranda-ng
/* chanlist_contains:
 *	  Returns non-0, if the chanlist contains the specified channel.
 */
int chanlist_contains(const char * chanlist, const char * channel)
{
	ASSERT_RETURNVALIFFAIL(VALIDPTR(channel), 0);

	return chanlist_find_channel(chanlist, channel, NULL, NULL) != NULL;
}
コード例 #27
0
ファイル: userlist.c プロジェクト: 0xmono/miranda-ng
int userlist_user_exists(const char * user_name)
{
	ASSERT_RETURNVALIFFAIL(
		VALIDPTR(s_userlistHash) && VALIDPTR(user_name), 0);
	return userlist_entry_by_name(user_name) != NULL;
}
コード例 #28
0
ファイル: os2fake-win.c プロジェクト: egraba/kbuild_openbsd
APIRET OS2ENTRY         DosQueryPathInfo(
                            PCSZ        pszPathName,
                            ULONG       ulInfoLevel,
                            PVOID       pInfoBuf,
                            ULONG       cbInfoBuf)
{
    APIRET  rc;                         /* Return code. */

    if (!VALIDPTR(pszPathName))
    {
        fprintf(stderr, "DosQueryPathInfo: pszPathName is an invalid pointer - %p\n", pszPathName);
        return ERROR_INVALID_PARAMETER;
    }

    if (!VALIDPTR(pInfoBuf))
    {
        fprintf(stderr, "DosQueryPathInfo: pInfoBuf is an invalid pointer - %p\n", pInfoBuf);
        return ERROR_INVALID_PARAMETER;
    }


    rc = ERROR_INVALID_PARAMETER;
    switch (ulInfoLevel)
    {
        case FIL_QUERYFULLNAME:
        {
            LPTSTR   lpDummy;
            if (GetFullPathName(pszPathName, cbInfoBuf, pInfoBuf, &lpDummy) > 0)
                rc = NO_ERROR;
            else
                rc = GetLastError();
            break;
        }

        case FIL_STANDARD:
            if (cbInfoBuf == sizeof(FILESTATUS3))
            {
                WIN32_FILE_ATTRIBUTE_DATA   fad;

                if (GetFileAttributesEx(pszPathName, GetFileExInfoStandard, &fad)) //W98, NT4 and above.
                {
                    PFILESTATUS3    pfst3 = (PFILESTATUS3)(pInfoBuf);

                    if (fad.nFileSizeHigh > 0)
                        rc = ERROR_BAD_LENGTH;
                    pfst3->cbFile = pfst3->cbFileAlloc = fad.nFileSizeLow;
                    pfst3->attrFile = ConvertAttributes(fad.dwFileAttributes);
                    *(PULONG)(&pfst3->fdateCreation) = ConvertFileTime(&fad.ftCreationTime);
                    *(PULONG)(&pfst3->fdateLastAccess) = ConvertFileTime(&fad.ftLastAccessTime);
                    *(PULONG)(&pfst3->fdateLastWrite) = ConvertFileTime(&fad.ftLastWriteTime);
                    rc = NO_ERROR;
                }
                else
                    rc = GetLastError();
            }
            else
                fprintf(stderr, "DosQueryPathInfo: FIL_STANDARD - invalid structure size (cbInfoBuf=%d)\n", cbInfoBuf);
            break;

        default:
            fprintf(stderr, "DosQueryPathInfo: ulInfoLevel=%d not supported\n", ulInfoLevel);
    }

    return rc;
}
コード例 #29
0
ファイル: Ahtrace.c プロジェクト: NevilleDNZ/algol68toc
void Agc_trace(
  SEGCTLPTR *heap_segments
)
{
  AREA    heap;
  AREA    area;			/* The current area being traced */
  TRACINGSTACK tstack;		/* Stack of areas to be traced */

  SEGCTLPTR segctlp;
  SEGCTLPTR *segctlpp;
  SIZE temp;

#ifndef	A_FUNNY_STEPAREAPTR	/* cop-out for weird architectures */
  {
    
	/* Check that STEPAREAPTR works correctly on this machine for this nastily aligned structure */
	/* If C compiler does tight packing, this could be a problem for the garbage collector */

	ASSERT_DECL( struct { PTR p1; char c; PTR p2; } *ass_struct = NIL )
	ASSERT_INIT( ( area.addr = (PTR)&ass_struct->c , area.size = sizeof(*ass_struct) ) );
	ASSERT_INIT( STEPAREA( area ) );
	ASSERT(area.addr == (PTR)&ass_struct->p2,Agc_collect,STEPAREA misbehaving);
  }
#endif

  heap.addr = SEGSTART( *heap_segments ); heap.size = 0 ;/* inital values to be improved in loop*/

  REPORT1(3, "%s\n", "Started trace... setting up bitmaps...");

  for ( segctlp = *heap_segments; segctlp != NIL; segctlp = segctlp->next )
  {
    REPORT6(6,"Agc_collect{mark}: segctlp=0x%p, elsize=%d, start=0x%p, end=0x%p, size=%d,els=%d\n",
	    (void *)segctlp,SEGELSIZE(segctlp),(void *)SEGSTART(segctlp),(void *)SEGEND(segctlp),SEGSIZE(segctlp),SEGELS(segctlp));

    if ( ! ( SEGELSIZE( segctlp ) > 0 && (char *)SEGEND( segctlp ) > (char *)SEGSTART( segctlp ) ) )
    {
      /* Segment control information has been corrupted. */
      /* Most likely this is because of a user scope/bound error, or CTRANS bug; though possibly a collector bug. */
      GC_ERROR(HEAP segments corrupt);
    }

    if ( (char *)SEGSTART( segctlp ) < (char *)(heap.addr) )
    {
      heap.size += (SIZE)((char *)(heap.addr) - (char *)SEGSTART( segctlp ));
      heap.addr = SEGSTART( segctlp );
    }
    
    if ( SEGEND( segctlp ) > (PTR)((char *)(heap.addr)+heap.size) )
      heap.size = (SIZE)((char *)SEGEND( segctlp ) - (char*)(heap.addr));

    GRAB_BITMAP( segctlp->bitmap, SEGELS( segctlp ) + 3 );
    SETMARK( segctlp->bitmap, SEGELS( segctlp ) + 0 );
    ASSERT(!TSTMARK(segctlp->bitmap,SEGELS(segctlp)+1),Agc_collect,bitmap trailer set at grab);
    SETMARK( segctlp->bitmap, SEGELS( segctlp ) + 2 );
    /* create an artificial endpoint which can be scanned to */
    REPORT2(6,"Agc_collect:\t\tbitmap, ptr=0x%p, size=%d\n", (void *)(segctlp->bitmap), SEGELS( segctlp ));
  }

  REPORT2(5,"Agc_collect: heap address=0x%p, heap size=%d\n",(void *)heap.addr,heap.size);

  INIT_STACK(tstack);
  ASSERT_INIT(PUSH(tstack,(PTR)Agc_collect,-42)); /* Assertion mark */
  PUSH(tstack, NIL, 0);				  /* identifies exhausted stack */

  REPORT1(3, "%s\n", "Initialising stack scan...");

  INIT_AREA(area);   /* set area to first area to search - could also PUSH
                        any additional areas (or use NEXT_AREA) */

  do
  {
    for ( ; !NILAREA(area); /* POP() at end of loop as it may contain statements */ )
    {

      REPORT3(6,"Agc_collect: AREA scan, ptr=0x%p -> 0x%p, size=%d\n",
	      (void *)area.addr,(void *)((char *)area.addr+area.size),area.size);

      ASSERT(area.size >= 0 && area.size < 100*1024*1024 /* 100Mb */,Agc_collect,area size not sensible);

      for ( ; area.size >= sizeof(PTR); STEPAREA(area) )
      {
	SIZE	els, el_in_seg;

	PTR p = * (PTR *) area.addr; /* View word as a pointer */

	REPORT3(9,"Agc_collect: AREA scan step, ptr=0x%p, size=%d, p=0x%p\n",
		(void *)area.addr,area.size,(void *)p);

	/* Continue loop if 'p' is unlikely to be a heap pointer.			*/
	/* Keeping the loop small may help some machines with small instruction caches.	*/

	if ( !VALIDPTR( p ) || !PTRINAREA(p,heap) ) continue;

	/* p is very likely to be a heap pointer */

	for ( segctlpp = heap_segments; (segctlp = *segctlpp) != NIL; segctlpp = &((segctlp)->next ))
	{
	  if ( (char *)p >= (char *)SEGSTART(segctlp) && (char *)p < (char *)SEGEND(segctlp) )
	  {
	    /* Segment for heap pointer */

	    goto found_segment;
	  }
	}

	/* Not a valid heap pointer */

	continue;		/* back to STEPAREA loop */

      found_segment:

	REPORT3(6,"Agc_collect, found_segment: ptr=0x%p, segctlp=0x%p, elsize=%d\n",
		(void *)p,(void *)segctlp,SEGELSIZE(segctlp));

	/*
	 **  	Move segment to front of segment list, to effect a 'cacheing' as in allocation.
	 **	We believe that there is locality in types of heap pointers,
	 **	(consider lists and trees) so it is likely that next
	 **	lookup will immediately succeed.
	 **	However a fast search startegy might be better ???
	 **
	 **	Note that typical programs only have a small number of segs,
	 **	many of which are infrequently used.
	 **		Multics Algol68 compiler uses 12 segs;
	 **		ELLA uses ??? segs.
	 */

	*segctlpp = segctlp->next;
	segctlp->next = *heap_segments;
	*heap_segments = segctlp;


#ifdef  MUST_POINT_TO_WORD
	/*
	 * Ignore pointers that are not word aligned,
	 * unless in a segment of objects of size that is not a multiple of word.
	 */

	if ( (SEGELSIZE(segctlp) & (WORDSIZE-1)) == 0 && (((CODEDPTR)(p) & (WORDSIZE-1)) != 0) )
	  continue;		/* p not to word aligned object, forget it */
#endif

#ifdef  MUST_POINT_TO_LWORD
	/*
	 * Ignore pointers that are not long word aligned,
	 * unless in a segment of objects of size that is not a multiple of long word.
	 */

	if ( (SEGELSIZE(segctlp) & (sizeof(long)-1)) == 0 && (((CODEDPTR)(p) & (sizeof(long)-1)) != 0) )
	  continue;		/* p not to long aligned object, forget it */
#endif


	IDENTIFY_ALIGN_EL( p, el_in_seg, segctlp );


#ifdef  MUST_POINT_TO_START
	/* Ignore pointers that point within objects	*/
	/* This could be implemented more efficiently	*/

	if ( p != * (PTR *) area.addr )
	  continue;		/* p not to start of element, forget it */
#endif

#ifdef	NO_GCMARK
	els = 1;
#else
	ANAL_DESC( els, p, area );
#endif

	REPORT3(6,"Agc_collect, aligned and analysed ptr: ptr=0x%p, element in seg=%d, elements=%d\n",
		(void *)p,el_in_seg,els);

#ifdef A_GC_HALFWORD_ALIGNED
      /* Interpret this as half word aligned (2byte) DJS 8/12/94 */
	/* +++ !!! ???
	 ** Crappy quick fix to keep elements word aligned for the Apollo
	 ** (also done for Sun/68000, though it has not been proved that this is necessary).
	 ** Apollo does not permit word objects to be aligned at any byte boundry,
	 ** even though 68020/68030 does.  This must be because C compiler generates
	 ** strange code, or page faults for words that straddle page boundries are
	 ** handled badly.
	 */

	if ( SEGELSIZE(segctlp) == 1 )
	{
	  if ( (long)p & 1 )
	  {
	    p--;
	    el_in_seg--;
	    els++;
	  }

	  if ( els & 1 )
	  {
	    els++;
	  }

	  if ( els <= 1 || els > SEGELS(segctlp) || p+(els*SEGELSIZE(segctlp)) > SEGEND(segctlp) )
	  {
	    els = 2;
	  }

	  REPORT3(6,"Agc_collect, adjusted to: ptr=0x%x, element in seg=%d, elements=%d\n",
		  p,el_in_seg,els);

	  goto els_sensible;
	}
#endif


#ifdef A_GC_WORD_ALIGNED

	/* +++ !!! ???
	 ** Crappy quick fix to keep elements word aligned.
	 */

	if ( SEGELSIZE(segctlp) == 1 )
	{
	  if ( !WORDALIGNED(p) )
	  {
	    int	offset = (int)((CODEDPTR)p & (WORDSIZE-1));
	    p = (char *)p - offset;
	    el_in_seg -= offset;
	    els += offset;
	  }

	  if ( !WORDALIGNED(els) )
	  {
	    els = (SIZE)ALIGN_NEXT(els,WORDSIZE);
	  }

	  if ( (els < WORDSIZE) || (els > SEGELS(segctlp)) || ((char *)p+(els*SEGELSIZE(segctlp)) > (char *)SEGEND(segctlp) ))
	  {
	    els = WORDSIZE;
	  }

	  REPORT3(6,"Agc_collect, adjusted to: ptr=0x%p, element in seg=%d, elements=%d\n",
		  (void *)p,el_in_seg,els);

	  goto els_sensible;
	}
#endif

	/* 'els' may be a very silly number, check it is reasonable	*/
	/* before doing arithmetic that may overflow.			*/

	if ( els <= 1 || els > SEGELS(segctlp) || (char *)p+(els*SEGELSIZE(segctlp)) > (char *)SEGEND(segctlp) )
	{
	  /* els = 1; assumed in case array descriptor mis analysed, the ptr is still valid */

	  if ( !TSTMARK( segctlp->bitmap, el_in_seg ) )
	  {
	    SETMARK( segctlp->bitmap, el_in_seg );

	    if ( SEGELSIZE(segctlp) >= PTRSIZE )
	    {
	      /* need only scan elements that are large enough to hold pointer */
	      PUSH( tstack, p, SEGELSIZE(segctlp) );

	      REPORT2(6,"Agc_collect: PUSH( ptr=0x%p, size=%d )\n",
		      (void *)p,SEGELSIZE(segctlp));
	    }
	  }
	}
	else
	{
	els_sensible:
	  CALCTSTMARKS( segctlp->bitmap, el_in_seg, els, temp );
	  if ( !RESTSTMARKS( segctlp->bitmap, el_in_seg, els, temp ) )
	  {
	    /*
	     ** At least one element in area has not been marked before.
	     **
	     ** We could just mark and push unmarked areas,
	     ** but this complicates logic for a fairly rare eventuality,
	     ** mainly caused by the trimming of heap rows.
	     */

	    SETMARKS( segctlp->bitmap, el_in_seg, els );

	    if ( SEGELSIZE(segctlp) >= PTRSIZE )
	    {
	      /* need only scan elements that are large enough to hold pointer */
	      PUSH( tstack, p, els*SEGELSIZE(segctlp) );

	      REPORT2(6,"Agc_collect: PUSH( ptr=0x%p, size=%d )\n",
		      (void *)p,els*SEGELSIZE(segctlp));
	    }
	  }
	}
      }
      area = POP(tstack);
    }
    /* Stack is exhausted, replace end marker */

    PUSH(tstack, NIL, 0);	/* identifies exhausted stack */

    NEXT_AREA(area);

    REPORT2(6,"Agc_collect: NEXT_AREA, ptr=0x%p, size=%d\n",(void *)area.addr,area.size);
  }
  while( area.addr != NIL );

  area = POP(tstack);		/* pop of (NIL, 0) to leave stack empty and tidy before calling FREE_STACK() */

  ASSERT_INIT( area=POP(tstack) );
  ASSERT(area.addr == (PTR)Agc_collect && area.size == -42,Agc_collect,tracing stack misuse);

  FREE_STACK(tstack);
  REPORT1(3, "%s\n", "End of trace");
}
コード例 #30
0
ファイル: os2fake-win.c プロジェクト: egraba/kbuild_openbsd
APIRET OS2ENTRY         DosFindFirst(
                            PCSZ        pszFileSpec,
                            PHDIR       phdir,
                            ULONG       flAttribute,
                            PVOID       pFindBuf,
                            ULONG       cbFindBuf,
                            PULONG      pcFileNames,
                            ULONG       ulInfoLevel)
{
    WIN32_FIND_DATA FindData;           /* Win32 Find data (returned by FindFirstFile) */
    APIRET          rc;

    if (!VALIDPTR(pszFileSpec))
    {
        fprintf(stderr, "DosFindFirst: pszFileSpec - %p\n", pszFileSpec);
        return ERROR_INVALID_PARAMETER;
    }

    if (!VALIDPTR(phdir))
    {
        fprintf(stderr, "DosFindFirst: phdir - %p\n", phdir);
        return ERROR_INVALID_PARAMETER;
    }

    if (!VALIDPTR(pFindBuf))
    {
        fprintf(stderr, "DosFindFirst: pfindbuf - %p\n", pFindBuf);
        return ERROR_INVALID_PARAMETER;
    }

    if (!VALIDPTR(pcFileNames))
    {
        fprintf(stderr, "DosFindFirst: pcFileNames - %p\n", pcFileNames);
        return ERROR_INVALID_PARAMETER;
    }

    if (*phdir != HDIR_CREATE)
    {
        fprintf(stderr, "DosFindFirst: *phdir != HDIR_CREATE - 0x%08x\n", *phdir);
        return ERROR_INVALID_PARAMETER;
    }

    switch (ulInfoLevel)
    {
        case FIL_STANDARD:
            if (cbFindBuf < sizeof(FILEFINDBUF3))
            {
                fprintf(stderr, "DosFindFirst: unsupported buffer size - %d\n", cbFindBuf);
                return ERROR_INVALID_PARAMETER;
            }
            break;

        default:
            fprintf(stderr, "DosFindFirst: invalid infolevel %d\n", ulInfoLevel);
            return ERROR_INVALID_PARAMETER;
    }

    *phdir = (HDIR)FindFirstFile(pszFileSpec, &FindData);
    if (*phdir != (HDIR)INVALID_HANDLE_VALUE)
    {
        PFILEFINDBUF3   pfindbuf = (PFILEFINDBUF3)pFindBuf;

        memcpy(pfindbuf->achName, FindData.cFileName, pfindbuf->cchName = strlen(FindData.cFileName) + 1);
        pfindbuf->cbFile = pfindbuf->cbFileAlloc = FindData.nFileSizeHigh > 0 ? 0xffffffff : FindData.nFileSizeLow;
        pfindbuf->attrFile = ConvertAttributes(FindData.dwFileAttributes);
        *(PULONG)(&pfindbuf->fdateCreation) = ConvertFileTime(&FindData.ftCreationTime);
        *(PULONG)(&pfindbuf->fdateLastAccess) = ConvertFileTime(&FindData.ftLastAccessTime);
        *(PULONG)(&pfindbuf->fdateLastWrite) = ConvertFileTime(&FindData.ftLastWriteTime);
        pfindbuf->oNextEntryOffset = 0;
        *pcFileNames = 1;
        rc = NO_ERROR;
    }
    else
        rc = GetLastError();

    return rc;
}