PackFiles NOT called???

Discuss and announce Total Commander plugins, addons and other useful tools here, both their usage and their development.

Moderators: Hacker, petermad, Stefan2, white

VSB
Member
Member
Posts: 136
Joined: 2006-12-12, 12:02 UTC
Location: Russia

Post by *VSB »

Well, adding dummy main function solve the problem, but was it correct solution?

Code: Select all

int main()
{
	return 0;
}
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

Linker requires main function only when using debug default libraries (Multi-threaded Debug) so you can just leave your empty main function - in release mode (Multi-threaded) linker will ignore it (you may even enclose it in #ifdef _DEBUG ... #endif block and it will work fine).
VSB
Member
Member
Posts: 136
Joined: 2006-12-12, 12:02 UTC
Location: Russia

Post by *VSB »

This better, i think

Code: Select all

#if  defined(_DEBUG) && defined(_MT)
int __cdecl main()
{
	return 0;
}
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

This would be even better. :)

Code: Select all

#if defined(_DEBUG) && defined(_MT) && defined(_WINDLL)
Last edited by MVV on 2010-07-13, 16:07 UTC, edited 2 times in total.
VSB
Member
Member
Posts: 136
Joined: 2006-12-12, 12:02 UTC
Location: Russia

Post by *VSB »

2MVV
ORLY?
_DLL defined only for non-static linking, when using msvcrt90.dll
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

Oops, you right. I thought that _DLL is defined when I'm compiling DLL... But now I see that it is defined when CRT is linked as dynamic library. :)

I corrected sample in previous post.

VS 10 doesn't require main function stub (BTW as I can remember VS 9 shouldn't require it too...). But it requires it if I redefine entry point (unfortunately I don't know how to distinguish theese two cases using predefined macros).
VSB
Member
Member
Posts: 136
Joined: 2006-12-12, 12:02 UTC
Location: Russia

Post by *VSB »

Well, _MT and _DLL are mutually exclusive
==========
And there is new question:
I have
WCHAR *s1, *s2, *s3;

I want that s3=s1+s2, but i don't know how do this without effect on s1 because wcscat(s1, s2) appends s2 to s1 and i need s1 unchanged
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

In C usual WCHAR* is a PWideChar in Delphi - you need to assign to it address of some buffer before using.

Well, first of all you need to decide allocation type for s3 - static or dynamic. Then you may copy s1 to s3 using wcscpy and then append s2 to s3 using wcscat.

Code: Select all

WCHAR buffer[1024];
s3=buffer; // static allocation
OR

Code: Select all

s3=new WCHAR[1024]; // dynamic allocation
And then:

Code: Select all

*s3=0;
wcscpy(s3, s1);
wcscat(s3, s2);
In case of dynamic allocation you must free memory after using s3:

Code: Select all

delete s3;
s3=0;
But you may simply use wstring class:

Code: Select all

wstring s1, s2, s3;
It allows to work with strings like in Delphi:

Code: Select all

s3=s1;
s3.append(s2);
OR

Code: Select all

s3=s1+s2;
If you need to get pointer to string you may use wstring::c_str() method:

Code: Select all

wprintf(L"%s", s3.c_str());
VSB
Member
Member
Posts: 136
Joined: 2006-12-12, 12:02 UTC
Location: Russia

Post by *VSB »

Thanks
========

Question:
What Regexp realisation for C++ support wchar_t ?
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50532
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Please don't use wcscpy and wcscat, they do not check the length and will therefore cause a crash if the string is too long. Instead, please use wcslcpy and wcslcat from the cunicode.c file from my sample plugins. Here they are:

Code: Select all

WCHAR* wcslcpy(WCHAR *str1,const WCHAR *str2,int imaxlen)
{
	if ((int)wcslen(str2)>=imaxlen-1) {
		wcsncpy(str1,str2,imaxlen-1);
		str1[imaxlen-1]=0;
	} else
		wcscpy(str1,str2);
	return str1;
}

WCHAR* wcslcat(WCHAR *str1,const WCHAR *str2,int imaxlen)
{
	int l1=(int)wcslen(str1);
	if ((int)wcslen(str2)+l1>=imaxlen-1) {
		wcsncpy(str1+l1,str2,imaxlen-1-l1);
		str1[imaxlen-1]=0;
	} else
		wcscat(str1,str2);
	return str1;
}
Author of Total Commander
https://www.ghisler.com
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

I think it would be easier to use lstrcpynW function - it appends NULL character even if iMaxLength is less than string length, and it is Windows API function so it doesn't require additional piece of code. :)
VSB
Member
Member
Posts: 136
Joined: 2006-12-12, 12:02 UTC
Location: Russia

Post by *VSB »

2ghisler(Author)

And what about wcscpy_s and wcscar_s?
====

Although, is there list of WinAPI NTFS-related (directory creation, file info etc.), which support path about 32000 Unicode characters (begining from "\\?\") instead of 260 characters, defined by MAX_PATH?
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50532
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

If your compiler supports them, then use them. Just don't use unchecked wcscpy and wcscat.
Author of Total Commander
https://www.ghisler.com
VSB
Member
Member
Posts: 136
Joined: 2006-12-12, 12:02 UTC
Location: Russia

Post by *VSB »

Well, I make function for creating directory even upper path doesn't exists, but I'm not sure, that it is correct.
Please, check it

Code: Select all

#define MY_MAX_PATH 32768	//REAL NTFS MAX_PATH
#define UNC_PREFIX L"\\\\?\\" 


BOOL my_CreateDirectoryW(
						 __in     LPCWSTR lpPathName,
						 __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes
						 )
{
	WCHAR *tmpchr;
	WCHAR tmpDir[MY_MAX_PATH];
	wcscpy_s(tmpDir,MY_MAX_PATH,lpPathName);
	WCHAR tmpUpDir[MY_MAX_PATH];
	wcscpy_s(tmpUpDir,MY_MAX_PATH,lpPathName);
	if (wcslen(wcsrchr(tmpUpDir,L'\\'))==1)
	{
		tmpchr=wcsrchr(tmpUpDir,L'\\');
		*tmpchr=L'\0';
	} 
	tmpchr=(WCHAR *)((DWORD)wcsrchr(tmpUpDir,L'\\')+sizeof(WCHAR));				//we need the last character
	*tmpchr=L'\0';
	if (!PathFileExistsW(tmpUpDir))												//there is no upper directory, try to create in
	{
		if ((wcscmp(tmpUpDir,tmpDir)==0)||(wcscmp(tmpUpDir,UNC_PREFIX)==0))		//there cant't upper directory
		{
			SetLastError(ERROR_PATH_NOT_FOUND);
			return FALSE;
		} 
		else																	//there can be
		{
			return my_CreateDirectoryW(tmpUpDir,lpSecurityAttributes);
		}
	}
	else
	{
		return CreateDirectoryW(tmpDir,lpSecurityAttributes);					//hl may be created only in existing directory
	}
}
Post Reply