security audit of explorer code...
strcpy -> lstrcpyn
strncpy -> lstrcpyn
[v]sprintf -> [v]snprintf
moved common Shell::get_path() subclass implementations into Shell::get_path_base() and made function overflow-proof
make other non-common subclass implementations of get_path overflow-proof
Modified: trunk/reactos/subsys/system/explorer/dialogs/searchprogram.cpp
Modified: trunk/reactos/subsys/system/explorer/explorer.cpp
Modified: trunk/reactos/subsys/system/explorer/notifyhook/notifyhook.c
Modified: trunk/reactos/subsys/system/explorer/shell/entries.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/entries.h
Modified: trunk/reactos/subsys/system/explorer/shell/fatfs.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/fatfs.h
Modified: trunk/reactos/subsys/system/explorer/shell/filechild.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/mainframe.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/ntobjfs.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/ntobjfs.h
Modified: trunk/reactos/subsys/system/explorer/shell/regfs.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/regfs.h
Modified: trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/shellfs.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/shellfs.h
Modified: trunk/reactos/subsys/system/explorer/shell/unixfs.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/unixfs.h
Modified: trunk/reactos/subsys/system/explorer/shell/winfs.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/winfs.h
Modified: trunk/reactos/subsys/system/explorer/taskbar/favorites.cpp
Modified: trunk/reactos/subsys/system/explorer/taskbar/startmenu.cpp
Modified: trunk/reactos/subsys/system/explorer/utility/shellclasses.cpp
Modified: trunk/reactos/subsys/system/explorer/utility/shellclasses.h
Modified: trunk/reactos/subsys/system/explorer/utility/utility.h
Modified: trunk/reactos/subsys/system/explorer/utility/xmlstorage.h

Modified: trunk/reactos/subsys/system/explorer/dialogs/searchprogram.cpp
--- trunk/reactos/subsys/system/explorer/dialogs/searchprogram.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/dialogs/searchprogram.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -150,7 +150,7 @@
 	_thread.Stop();
 
 	TCHAR buffer[1024];
-	GetWindowText(GetDlgItem(_hwnd, IDC_FILTER), buffer, 1024);
+	GetWindowText(GetDlgItem(_hwnd, IDC_FILTER), buffer, COUNTOF(buffer));
 #ifndef __WINE__ ///@todo _tcslwr() for Wine
 	_tcslwr(buffer);
 #endif
@@ -191,7 +191,7 @@
 			if (SUCCEEDED(hr)) {
 				TCHAR entry_path[MAX_PATH];
 
-				entry->get_path(entry_path);
+				entry->get_path(entry_path, COUNTOF(entry_path));
 
 				String menu_path;
 
@@ -231,8 +231,8 @@
 	String lwr_name = cache_entry._entry->_display_name;
 
 #ifndef __WINE__ ///@todo _tcslwr() for Wine
-	_tcslwr((LPTSTR)lwr_path.c_str());
-	_tcslwr((LPTSTR)lwr_name.c_str());
+	_tcslwr(&lwr_path.at(0));
+	_tcslwr(&lwr_name.at(0));
 #endif
 
 	if (_lwr_filter.empty())

Modified: trunk/reactos/subsys/system/explorer/explorer.cpp
--- trunk/reactos/subsys/system/explorer/explorer.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/explorer.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -183,7 +183,7 @@
 const FileTypeInfo& FileTypeManager::operator[](String ext)
 {
 #ifndef __WINE__ ///@todo _tcslwr() for Wine
-	_tcslwr((LPTSTR)ext.c_str());
+	_tcslwr(&ext.at(0));
 #endif
 
 	iterator found = find(ext);
@@ -230,7 +230,7 @@
 		if (type._neverShowExt && !dont_hide_ext) {
 			int len = ext - entry->_data.cFileName;
 			entry->_display_name = (LPTSTR) malloc((len+1)*sizeof(TCHAR));
-			_tcsncpy(entry->_display_name, entry->_data.cFileName, len);
+			lstrcpyn(entry->_display_name, entry->_data.cFileName, len);
 			entry->_display_name[len] = TEXT('\0');
 		}
 
@@ -416,7 +416,7 @@
 	CachePair key(path, idx);
 
 #ifndef __WINE__ ///@todo _tcslwr() for Wine
-	_tcslwr((LPTSTR)key.first.c_str());
+	_tcslwr(&key.first.at(0));
 #endif
 
 	PathIdxMap::iterator found = _pathIdxMap.find(key);

Modified: trunk/reactos/subsys/system/explorer/notifyhook/notifyhook.c
--- trunk/reactos/subsys/system/explorer/notifyhook/notifyhook.c	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/notifyhook/notifyhook.c	2005-09-12 21:46:09 UTC (rev 17825)
@@ -108,7 +108,7 @@
 		struct COPYDATA_STRUCT* cds = (struct COPYDATA_STRUCT*) data->lpData;
 
 		*phwnd = cds->_hwnd;
-		strncpy(buffer, cds->_path, size);
+		lstrcpyn(buffer, cds->_path, size);
 
 		return cds->_len;
 	} else

Modified: trunk/reactos/subsys/system/explorer/shell/entries.cpp
--- trunk/reactos/subsys/system/explorer/shell/entries.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/entries.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -325,7 +325,7 @@
 
 	ICON_ID icon_id = ICID_NONE;
 
-	if (get_path(path) && _tcsncmp(path,TEXT("::{"),3))
+	if (get_path(path, COUNTOF(path)) && _tcsncmp(path,TEXT("::{"),3))
 		icon_id = g_Globals._icon_cache.extract(path);
 
 	if (icon_id == ICID_NONE) {
@@ -392,7 +392,7 @@
 {
 	TCHAR cmd[MAX_PATH];
 
-	if (!get_path(cmd))
+	if (!get_path(cmd, COUNTOF(cmd)))
 		return FALSE;
 
 	 // add path to the recent file list
@@ -453,7 +453,7 @@
 {
 	TCHAR path[MAX_PATH];
 /*
-	if (!get_path(path))
+	if (!get_path(path, COUNTOF(path)))
 		return E_FAIL;
 
 	ShellPath shell_path(path);
@@ -479,7 +479,7 @@
 	if (!_up)
 		return E_INVALIDARG;
 
-	if (!_up->get_path(path))
+	if (!_up->get_path(path, COUNTOF(path)))
 		return E_FAIL;
 
 	ShellPath shell_path(path);
@@ -505,7 +505,108 @@
 	return hr;
 }
 
+ // get full path of specified directory entry
+bool Entry::get_path_base ( PTSTR path, size_t path_count, ENTRY_TYPE etype ) const
+{
+	int level = 0;
+	size_t len = 0;
+	size_t l = 0;
+	LPCTSTR name = NULL;
+	TCHAR buffer[MAX_PATH];
 
+	if ( !path || 0 == path_count )
+		return false;
+
+	const Entry* entry;
+	if ( path_count > 1 )
+	{
+		for(entry=this; entry; level++) {
+			l = 0;
+
+			if (entry->_etype == etype) {
+				name = entry->_data.cFileName;
+
+				for(LPCTSTR s=name; *s && *s!=TEXT('/') && *s!=TEXT('\\'); s++)
+					++l;
+
+				if (!entry->_up)
+					break;
+			} else {
+				if (entry->get_path(buffer, COUNTOF(buffer))) {
+					l = _tcslen(buffer);
+					name = buffer;
+
+					/* special handling of drive names */
+					if (l>0 && buffer[l-1]=='\\' && path[0]=='\\')
+						--l;
+
+					if ( len+l >= path_count )
+					{
+						if ( l + 1 > path_count )
+							len = 0;
+						else
+							len = path_count - l - 1;
+					}
+					memmove(path+l, path, len*sizeof(TCHAR));
+					if ( l+1 >= path_count )
+						l = path_count - 1;
+					memcpy(path, name, l*sizeof(TCHAR));
+					len += l;
+				}
+
+				entry = NULL;
+				break;
+			}
+
+			if (l > 0) {
+				if ( len+l+1 >= path_count )
+				{
+					/* compare to 2 here because of terminator plus the '\\' we prepend */
+					if ( l + 2 > path_count )
+						len = 0;
+					else
+						len = path_count - l - 2;
+				}
+				memmove(path+l+1, path, len*sizeof(TCHAR));
+				/* compare to 2 here because of terminator plus the '\\' we prepend */
+				if ( l+2 >= path_count )
+					l = path_count - 2;
+				memcpy(path+1, name, l*sizeof(TCHAR));
+				len += l+1;
+
+				if ( etype == ET_WINDOWS && entry->_up && !(entry->_up->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))	// a NTFS stream?
+					path[0] = TEXT(':');
+				else
+					path[0] = TEXT('\\');
+			}
+
+			entry = entry->_up;
+		}
+
+		if (entry) {
+			if ( len+l >= path_count )
+			{
+				if ( l + 1 > path_count )
+					len = 0;
+				else
+					len = path_count - l - 1;
+			}
+			memmove(path+l, path, len*sizeof(TCHAR));
+			if ( l+1 >= path_count )
+				l = path_count - 1;
+			memcpy(path, name, l*sizeof(TCHAR));
+			len += l;
+		}
+
+		if ( !level && (len+1 < path_count) )
+			path[len++] = TEXT('\\');
+	}
+
+	path[len] = TEXT('\0');
+
+	return true;
+}
+
  // recursively free all child entries
 void Entry::free_subentries()
 {

Modified: trunk/reactos/subsys/system/explorer/shell/entries.h
--- trunk/reactos/subsys/system/explorer/shell/entries.h	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/entries.h	2005-09-12 21:46:09 UTC (rev 17825)
@@ -108,11 +108,14 @@
 	virtual void		read_directory(int scan_flags=SCAN_ALL) {}
 	virtual const void*	get_next_path_component(const void*) const {return NULL;}
 	virtual Entry*		find_entry(const void*) {return NULL;}
-	virtual bool		get_path(PTSTR path) const = 0;
+	virtual bool		get_path(PTSTR path, size_t path_count) const = 0;
 	virtual ShellPath	create_absolute_pidl() const {return (LPCITEMIDLIST)NULL;}
 	virtual HRESULT		GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
 	virtual BOOL		launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
 	virtual HRESULT		do_context_menu(HWND hwnd, const POINT& pos, CtxMenuInterfaces& cm_ifs);
+
+protected:
+	bool get_path_base(PTSTR path, size_t path_count, ENTRY_TYPE etype) const;
 };
 
 

Modified: trunk/reactos/subsys/system/explorer/shell/fatfs.cpp
--- trunk/reactos/subsys/system/explorer/shell/fatfs.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/fatfs.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -244,67 +244,9 @@
 
 
  // get full path of specified directory entry
-bool FATEntry::get_path(PTSTR path) const
+bool FATEntry::get_path(PTSTR path, size_t path_count) const
 {
-	int level = 0;
-	int len = 0;
-	int l = 0;
-	LPCTSTR name = NULL;
-	TCHAR buffer[MAX_PATH];
-
-	const Entry* entry;
-	for(entry=this; entry; level++) {
-		l = 0;
-
-		if (entry->_etype == ET_FAT) {
-			name = entry->_data.cFileName;
-
-			for(LPCTSTR s=name; *s && *s!=TEXT('/') && *s!=TEXT('\\'); s++)
-				++l;
-
-			if (!entry->_up)
-				break;
-		} else {
-			if (entry->get_path(buffer)) {
-				l = _tcslen(buffer);
-				name = buffer;
-
-				/* special handling of drive names */
-				if (l>0 && buffer[l-1]=='\\' && path[0]=='\\')
-					--l;
-
-				memmove(path+l, path, len*sizeof(TCHAR));
-				memcpy(path, name, l*sizeof(TCHAR));
-				len += l;
-			}
-
-			entry = NULL;
-			break;
-		}
-
-		if (l > 0) {
-			memmove(path+l+1, path, len*sizeof(TCHAR));
-			memcpy(path+1, name, l*sizeof(TCHAR));
-			len += l+1;
-
-			path[0] = TEXT('\\');
-		}
-
-		entry = entry->_up;
-	}
-
-	if (entry) {
-		memmove(path+l, path, len*sizeof(TCHAR));
-		memcpy(path, name, l*sizeof(TCHAR));
-		len += l;
-	}
-
-	if (!level)
-		path[len++] = TEXT('\\');
-
-	path[len] = TEXT('\0');
-
-	return true;
+	return get_path_base ( path, path_count, ET_FAT );
 }
 
 ShellPath FATEntry::create_absolute_pidl() const
@@ -315,7 +257,7 @@
 /* prepend root path if the drive is currently actually mounted in the file system -> return working PIDL
 	TCHAR path[MAX_PATH];
 
-	if (get_path(path))
+	if (get_path(path, COUNTOF(path)))
 		return ShellPath(path);
 
 	return ShellPath();

Modified: trunk/reactos/subsys/system/explorer/shell/fatfs.h
--- trunk/reactos/subsys/system/explorer/shell/fatfs.h	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/fatfs.h	2005-09-12 21:46:09 UTC (rev 17825)
@@ -34,7 +34,7 @@
 protected:
 	FATEntry() : Entry(ET_FAT) {}
 
-	virtual bool get_path(PTSTR path) const;
+	virtual bool get_path(PTSTR path, size_t path_count) const;
 	virtual ShellPath create_absolute_pidl() const;
 
 	DWORD	_cluster;

Modified: trunk/reactos/subsys/system/explorer/shell/filechild.cpp
--- trunk/reactos/subsys/system/explorer/shell/filechild.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/filechild.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -280,7 +280,7 @@
 			_right->set_header();
 		}
 
-		entry->get_path(_path);
+		entry->get_path(_path, COUNTOF(_path));
 	}
 
 	if (_hwnd)	// only change window title if the window already exists
@@ -453,7 +453,7 @@
 			TCHAR path[MAX_PATH];
 
 			if (_left && _left->_cur) {
-				_left->_cur->get_path(path);
+				_left->_cur->get_path(path, COUNTOF(path));
 				SetCurrentDirectory(path);
 			}
 

Modified: trunk/reactos/subsys/system/explorer/shell/mainframe.cpp
--- trunk/reactos/subsys/system/explorer/shell/mainframe.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/mainframe.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -1608,7 +1608,7 @@
 
 		TCHAR path[MAX_PATH];
 
-		if (shell_entry->get_path(path)) {
+		if (shell_entry->get_path(path,COUNTOF(path))) {
 			String url;
 
 			if (path[0] == ':')

Modified: trunk/reactos/subsys/system/explorer/shell/ntobjfs.cpp
--- trunk/reactos/subsys/system/explorer/shell/ntobjfs.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/ntobjfs.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -237,12 +237,12 @@
 			} else {
 				info->type.string_ptr = TEXT("");
 			}
-			wcscpyn(p, info->name.string_ptr, _MAX_PATH);
+			lstrcpynW(p, info->name.string_ptr, _MAX_PATH);
 #else
 			WideCharToMultiByte(CP_ACP, 0, info->name.string_ptr, info->name.string_len, p, MAX_PATH, 0, 0);
 #endif
 
-			lstrcpy(w32fd.cFileName, p);
+			lstrcpyn(w32fd.cFileName, p, sizeof(w32fd.cFileName) / sizeof(0[w32fd.cFileName]));
 
 			const LPCWSTR* tname = NTDLL::s_ObjectTypes;
 			OBJECT_TYPE type = UNKNOWN_OBJECT_TYPE;
@@ -379,67 +379,9 @@
 
 
  // get full path of specified directory entry
-bool NtObjEntry::get_path(PTSTR path) const
+bool NtObjEntry::get_path(PTSTR path, size_t path_count) const
 {
-	int level = 0;
-	int len = 0;
-	int l = 0;
-	LPCTSTR name = NULL;
-	TCHAR buffer[MAX_PATH];
-
-	const Entry* entry;
-	for(entry=this; entry; level++) {
-		l = 0;
-
-		if (entry->_etype == ET_NTOBJS) {
-			name = entry->_data.cFileName;
-
-			for(LPCTSTR s=name; *s && *s!=TEXT('/') && *s!=TEXT('\\'); s++)
-				++l;
-
-			if (!entry->_up)
-				break;
-		} else {
-			if (entry->get_path(buffer)) {
-				l = _tcslen(buffer);
-				name = buffer;
-
-				/* special handling of drive names */
-				if (l>0 && buffer[l-1]=='\\' && path[0]=='\\')
-					--l;
-
-				memmove(path+l, path, len*sizeof(TCHAR));
-				memcpy(path, name, l*sizeof(TCHAR));
-				len += l;
-			}
-
-			entry = NULL;
-			break;
-		}
-
-		if (l > 0) {
-			memmove(path+l+1, path, len*sizeof(TCHAR));
-			memcpy(path+1, name, l*sizeof(TCHAR));
-			len += l+1;
-
-			path[0] = TEXT('\\');
-		}
-
-		entry = entry->_up;
-	}
-
-	if (entry) {
-		memmove(path+l, path, len*sizeof(TCHAR));
-		memcpy(path, name, l*sizeof(TCHAR));
-		len += l;
-	}
-
-	if (!level)
-		path[len++] = TEXT('\\');
-
-	path[len] = TEXT('\0');
-
-	return true;
+	return get_path_base ( path, path_count, ET_NTOBJS );
 }
 
 BOOL NtObjEntry::launch_entry(HWND hwnd, UINT nCmdShow)

Modified: trunk/reactos/subsys/system/explorer/shell/ntobjfs.h
--- trunk/reactos/subsys/system/explorer/shell/ntobjfs.h	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/ntobjfs.h	2005-09-12 21:46:09 UTC (rev 17825)
@@ -91,7 +91,7 @@
 protected:
 	NtObjEntry(OBJECT_TYPE type) : Entry(ET_NTOBJS), _type(type) {}
 
-	virtual bool get_path(PTSTR path) const;
+	virtual bool get_path(PTSTR path, size_t path_count) const;
 	virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow);
 };
 

Modified: trunk/reactos/subsys/system/explorer/shell/regfs.cpp
--- trunk/reactos/subsys/system/explorer/shell/regfs.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/regfs.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -223,67 +223,9 @@
 
 
  // get full path of specified registry entry
-bool RegEntry::get_path(PTSTR path) const
+bool RegEntry::get_path(PTSTR path, size_t path_count) const
 {
-	int level = 0;
-	int len = 0;
-	int l = 0;
-	LPCTSTR name = NULL;
-	TCHAR buffer[MAX_PATH];
-
-	const Entry* entry;
-	for(entry=this; entry; level++) {
-		l = 0;
-
-		if (entry->_etype == ET_REGISTRY) {
-			name = entry->_data.cFileName;
-
-			for(LPCTSTR s=name; *s && *s!=TEXT('/') && *s!=TEXT('\\'); s++)
-				++l;
-
-			if (!entry->_up)
-				break;
-		} else {
-			if (entry->get_path(buffer)) {
-				l = _tcslen(buffer);
-				name = buffer;
-
-				/* special handling of drive names */
-				if (l>0 && buffer[l-1]=='\\' && path[0]=='\\')
-					--l;
-
-				memmove(path+l, path, len*sizeof(TCHAR));
-				memcpy(path, name, l*sizeof(TCHAR));
-				len += l;
-			}
-
-			entry = NULL;
-			break;
-		}
-
-		if (l > 0) {
-			memmove(path+l+1, path, len*sizeof(TCHAR));
-			memcpy(path+1, name, l*sizeof(TCHAR));
-			len += l+1;
-
-			path[0] = TEXT('\\');
-		}
-
-		entry = entry->_up;
-	}
-
-	if (entry) {
-		memmove(path+l, path, len*sizeof(TCHAR));
-		memcpy(path, name, l*sizeof(TCHAR));
-		len += l;
-	}
-
-	if (!level)
-		path[len++] = TEXT('\\');
-
-	path[len] = TEXT('\0');
-
-	return true;
+	return get_path_base ( path, path_count, ET_REGISTRY );
 }
 
 BOOL RegEntry::launch_entry(HWND hwnd, UINT nCmdShow)

Modified: trunk/reactos/subsys/system/explorer/shell/regfs.h
--- trunk/reactos/subsys/system/explorer/shell/regfs.h	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/regfs.h	2005-09-12 21:46:09 UTC (rev 17825)
@@ -34,7 +34,7 @@
 protected:
 	RegEntry() : Entry(ET_REGISTRY) {}
 
-	virtual bool get_path(PTSTR path) const;
+	virtual bool get_path(PTSTR path, size_t path_count) const;
 	virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow);
 };
 

Modified: trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp
--- trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -626,7 +626,7 @@
 
 		TCHAR path[MAX_PATH];
 
-		if (shell_entry->get_path(path)) {
+		if (shell_entry->get_path(path, COUNTOF(path))) {
 			String url;
 
 			if (path[0] == ':')

Modified: trunk/reactos/subsys/system/explorer/shell/shellfs.cpp
--- trunk/reactos/subsys/system/explorer/shell/shellfs.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/shellfs.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -126,8 +126,10 @@
 
 
  // get full path of a shell entry
-bool ShellEntry::get_path(PTSTR path) const
+bool ShellEntry::get_path(PTSTR path, size_t path_count) const
 {
+	if ( !path || 0 == path_count )
+		return false;
 /*
 	path[0] = TEXT('\0');
 
@@ -138,7 +140,7 @@
 	LPCTSTR ret = fs_path;
 
 	if (ret) {
-		_tcscpy(path, ret);
+		lstrcpyn(path, ret, path_count);
 		return true;
 	} else
 		return false;
@@ -146,10 +148,13 @@
 
 
  // get full path of a shell folder
-bool ShellDirectory::get_path(PTSTR path) const
+bool ShellDirectory::get_path(PTSTR path, size_t path_count) const
 {
 	CONTEXT("ShellDirectory::get_path()");
 
+	if ( !path || 0 == path_count )
+		return false;
+
 	path[0] = TEXT('\0');
 
 	if (_folder.empty())
@@ -163,7 +168,7 @@
 	if (!(attribs & SFGAO_FILESYSTEM))
 		return false;
 
-	if (FAILED(path_from_pidl(get_parent_folder(), &*_pidl, path, MAX_PATH)))
+	if (FAILED(path_from_pidl(get_parent_folder(), &*_pidl, path, path_count)))
 		return false;
 
 	return true;
@@ -235,11 +240,12 @@
 
 	TCHAR buffer[MAX_PATH];
 
-	if ((scan_flags&SCAN_FILESYSTEM) && get_path(buffer) && _tcsncmp(buffer,TEXT("::{"),3)) {
+	if ((scan_flags&SCAN_FILESYSTEM) && get_path(buffer, COUNTOF(buffer)) && _tcsncmp(buffer,TEXT("::{"),3)) {
 		Entry* entry = NULL;	// eliminate useless GCC warning by initializing entry
 
 		LPTSTR p = buffer + _tcslen(buffer);
 
+		// TODO FIXME - this can overflow
 		lstrcpy(p, TEXT("\\*"));
 
 		WIN32_FIND_DATA w32fd;

Modified: trunk/reactos/subsys/system/explorer/shell/shellfs.h
--- trunk/reactos/subsys/system/explorer/shell/shellfs.h	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/shellfs.h	2005-09-12 21:46:09 UTC (rev 17825)
@@ -32,7 +32,7 @@
 	ShellEntry(Entry* parent, LPITEMIDLIST shell_path) : Entry(parent, ET_SHELL), _pidl(shell_path) {}
 	ShellEntry(Entry* parent, const ShellPath& shell_path) : Entry(parent, ET_SHELL), _pidl(shell_path) {}
 
-	virtual bool		get_path(PTSTR path) const;
+	virtual bool		get_path(PTSTR path, size_t path_count) const;
 	virtual ShellPath	create_absolute_pidl() const;
 	virtual HRESULT		GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
 	virtual BOOL		launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
@@ -103,7 +103,7 @@
 	virtual const void* get_next_path_component(const void*) const;
 	virtual Entry* find_entry(const void*);
 
-	virtual bool get_path(PTSTR path) const;
+	virtual bool get_path(PTSTR path, size_t path_count) const;
 
 	int	extract_icons();
 

Modified: trunk/reactos/subsys/system/explorer/shell/unixfs.cpp
--- trunk/reactos/subsys/system/explorer/shell/unixfs.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/unixfs.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -156,40 +156,68 @@
 
 
  // get full path of specified directory entry
-void UnixEntry::get_path(PTSTR path) const
+bool UnixEntry::get_path(PTSTR path, size_t path_count) const
 {
 	int level = 0;
-	int len = 0;
+	size_t len = 0;
 
-	for(const Entry* entry=this; entry; level++) {
-		LPCTSTR name = entry->_data.cFileName;
-		int l = 0;
+	if ( !path || 0 == path_count )
+		return false;
 
-		for(LPCTSTR s=name; *s && *s!=TEXT('/'); s++)
-			++l;
+	if ( path_count > 1 )
+	{
+		for(const Entry* entry=this; entry; level++) {
+			LPCTSTR name = entry->_data.cFileName;
+			size_t l = 0;
 
-		if (entry->_up) {
-			if (l > 0) {
-				memmove(path+l+1, path, len*sizeof(TCHAR));
-				memcpy(path+1, name, l*sizeof(TCHAR));
-				len += l+1;
+			for(LPCTSTR s=name; *s && *s!=TEXT('/'); s++)
+				++l;
 
-				path[0] = TEXT('/');
+			if (entry->_up) {
+				if (l > 0) {
+					if ( len+l+1 >= path_count )
+					{
+						/* compare to 2 here because of terminator plus the '\\' we prepend */
+						if ( l + 2 > path_count )
+							len = 0;
+						else
+							len = path_count - l - 2;
+					}
+					memmove(path+l+1, path, len*sizeof(TCHAR));
+					/* compare to 2 here because of terminator plus the '\\' we prepend */
+					if ( l+2 >= path_count )
+						l = path_count - 2;
+					memcpy(path+1, name, l*sizeof(TCHAR));
+					len += l+1;
+
+					path[0] = TEXT('/');
+				}
+
+				entry = entry->_up;
+			} else {
+				if ( len+l >= path_count )
+				{
+					if ( l + 1 > path_count )
+						len = 0;
+					else
+						len = path_count - l - 1;
+				}
+				memmove(path+l, path, len*sizeof(TCHAR));
+				if ( l+1 >= path_count )
+					l = path_count - 1;
+				memcpy(path, name, l*sizeof(TCHAR));
+				len += l;
+				break;
 			}
+		}
 
-			entry = entry->_up;
-		} else {
-			memmove(path+l, path, len*sizeof(TCHAR));
-			memcpy(path, name, l*sizeof(TCHAR));
-			len += l;
-			break;
-		}
+		if ( !level && (len+1 < path_count) )
+			path[len++] = TEXT('/');
 	}
 
-	if (!level)
-		path[len++] = TEXT('/');
+	path[len] = TEXT('\0');
 
-	path[len] = TEXT('\0');
+	return true;
 }
 
 #endif // __WINE__

Modified: trunk/reactos/subsys/system/explorer/shell/unixfs.h
--- trunk/reactos/subsys/system/explorer/shell/unixfs.h	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/unixfs.h	2005-09-12 21:46:09 UTC (rev 17825)
@@ -35,7 +35,7 @@
 protected:
 	UnixEntry() : Entry(ET_UNIX) {}
 
-	virtual void get_path(PTSTR path) const;
+	virtual bool get_path(PTSTR path, size_t path_count) const;
 };
 
 struct UnixDirectory : public UnixEntry, public Directory

Modified: trunk/reactos/subsys/system/explorer/shell/winfs.cpp
--- trunk/reactos/subsys/system/explorer/shell/winfs.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/winfs.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -229,70 +229,9 @@
 
 
  // get full path of specified directory entry
-bool WinEntry::get_path(PTSTR path) const
+bool WinEntry::get_path(PTSTR path, size_t path_count) const
 {
-	int level = 0;
-	int len = 0;
-	int l = 0;
-	LPCTSTR name = NULL;
-	TCHAR buffer[MAX_PATH];
-
-	const Entry* entry;
-	for(entry=this; entry; level++) {
-		l = 0;
-
-		if (entry->_etype == ET_WINDOWS) {
-			name = entry->_data.cFileName;
-
-			for(LPCTSTR s=name; *s && *s!=TEXT('/') && *s!=TEXT('\\'); s++)
-				++l;
-
-			if (!entry->_up)
-				break;
-		} else {
-			if (entry->get_path(buffer)) {
-				l = _tcslen(buffer);
-				name = buffer;
-
-				/* special handling of drive names */
-				if (l>0 && buffer[l-1]=='\\' && path[0]=='\\')
-					--l;
-
-				memmove(path+l, path, len*sizeof(TCHAR));
-				memcpy(path, name, l*sizeof(TCHAR));
-				len += l;
-			}
-
-			entry = NULL;
-			break;
-		}
-
-		if (l > 0) {
-			memmove(path+l+1, path, len*sizeof(TCHAR));
-			memcpy(path+1, name, l*sizeof(TCHAR));
-			len += l+1;
-
-			if (entry->_up && !(entry->_up->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))	// a NTFS stream?
-				path[0] = TEXT(':');
-			else
-				path[0] = TEXT('\\');
-		}
-
-		entry = entry->_up;
-	}
-
-	if (entry) {
-		memmove(path+l, path, len*sizeof(TCHAR));
-		memcpy(path, name, l*sizeof(TCHAR));
-		len += l;
-	}
-
-	if (!level)
-		path[len++] = TEXT('\\');
-
-	path[len] = TEXT('\0');
-
-	return true;
+	return get_path_base ( path, path_count, ET_WINDOWS );
 }
 
 ShellPath WinEntry::create_absolute_pidl() const
@@ -301,7 +240,7 @@
 
 	TCHAR path[MAX_PATH];
 
-	if (get_path(path))
+	if (get_path(path, COUNTOF(path)))
 		return ShellPath(path);
 
 	return ShellPath();

Modified: trunk/reactos/subsys/system/explorer/shell/winfs.h
--- trunk/reactos/subsys/system/explorer/shell/winfs.h	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/shell/winfs.h	2005-09-12 21:46:09 UTC (rev 17825)
@@ -34,7 +34,7 @@
 protected:
 	WinEntry() : Entry(ET_WINDOWS) {}
 
-	virtual bool get_path(PTSTR path) const;
+	virtual bool get_path(PTSTR path, size_t path_count) const;
 	virtual ShellPath create_absolute_pidl() const;
 };
 

Modified: trunk/reactos/subsys/system/explorer/taskbar/favorites.cpp
--- trunk/reactos/subsys/system/explorer/taskbar/favorites.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/taskbar/favorites.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -395,7 +395,7 @@
 				ShellDirectory new_dir(dir._folder, static_cast<ShellEntry*>(entry)->_pidl, hwnd);
 				new_folder._bookmarks.import_IE_favorites(new_dir, hwnd);
 			} else {
-				entry->get_path(path);
+				entry->get_path(path, COUNTOF(path));
 				ShellDirectory new_dir(GetDesktopFolder(), path, hwnd);
 				new_folder._bookmarks.import_IE_favorites(new_dir, hwnd);
 			}
@@ -406,7 +406,7 @@
 
 			bookmark._name = DecodeXMLString(name);
 
-			entry->get_path(path);
+			entry->get_path(path, COUNTOF(path));
 			_tsplitpath(path, NULL, NULL, NULL, ext);
 
 			if (!_tcsicmp(ext, TEXT(".url"))) {

Modified: trunk/reactos/subsys/system/explorer/taskbar/startmenu.cpp
--- trunk/reactos/subsys/system/explorer/taskbar/startmenu.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/taskbar/startmenu.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -249,7 +249,7 @@
 		_tcscat(ignore_path, ignore_dir);
 		_tcscat(ignore_name, ignore_ext);
 
-		dir.get_path(dir_path);
+		dir.get_path(dir_path, COUNTOF(dir_path));
 
 		if (_tcsicmp(trim_path_slash(dir_path), trim_path_slash(ignore_path)))
 			*ignore_name = '\0';
@@ -1286,7 +1286,7 @@
 			else {
 				TCHAR path[MAX_PATH];
 
-				if (entry->get_path(path))
+				if (entry->get_path(path, COUNTOF(path)))
 					new_folders.push_back(path);
 			}
 

Modified: trunk/reactos/subsys/system/explorer/utility/shellclasses.cpp
--- trunk/reactos/subsys/system/explorer/utility/shellclasses.cpp	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/utility/shellclasses.cpp	2005-09-12 21:46:09 UTC (rev 17825)
@@ -44,7 +44,7 @@
 
  // helper functions for string copying
 
-LPSTR strcpyn(LPSTR dest, LPCSTR source, size_t count)
+/*LPSTR strcpyn(LPSTR dest, LPCSTR source, size_t count)
 {
 	LPCSTR s;
 	LPSTR d = dest;
@@ -64,7 +64,7 @@
 		count--;
 
 	return dest;
-}
+}*/
 
 
 String COMException::toString() const

Modified: trunk/reactos/subsys/system/explorer/utility/shellclasses.h
--- trunk/reactos/subsys/system/explorer/utility/shellclasses.h	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/utility/shellclasses.h	2005-09-12 21:46:09 UTC (rev 17825)
@@ -85,7 +85,7 @@
 				LocalFree(pBuf);
 			 } else {
 				TCHAR buffer[128];
-				_stprintf(buffer, TEXT("unknown Exception: 0x%08lX"), _hr);
+				_sntprintf(buffer, COUNTOF(buffer), TEXT("unknown Exception: 0x%08lX"), _hr);
 				_msg = buffer;
 			 }
 		}
@@ -769,14 +769,14 @@
 
 #ifdef UNICODE
 #define	StrRet StrRetW
-#define	tcscpyn wcscpyn
+//#define	tcscpyn wcscpyn
 #else
 #define	StrRet StrRetA
-#define	tcscpyn strcpyn
+//#define	tcscpyn strcpyn
 #endif
 
-extern LPSTR strcpyn(LPSTR dest, LPCSTR source, size_t count);
-extern LPWSTR wcscpyn(LPWSTR dest, LPCWSTR source, size_t count);
+//extern LPSTR strcpyn(LPSTR dest, LPCSTR source, size_t count);
+//extern LPWSTR wcscpyn(LPWSTR dest, LPCWSTR source, size_t count);
 
  /// easy retrieval of multi byte strings out of STRRET structures
 struct StrRetA : public STRRET
@@ -795,11 +795,11 @@
 			break;
 
 		  case STRRET_OFFSET:
-			strcpyn(b, (LPCSTR)&shiid+UNION_MEMBER(uOffset), l);
+			lstrcpynA(b, (LPCSTR)&shiid+UNION_MEMBER(uOffset), l);
 			break;
 
 		  case STRRET_CSTR:
-			strcpyn(b, UNION_MEMBER(cStr), l);
+			lstrcpynA(b, UNION_MEMBER(cStr), l);
 		}
 	}
 };
@@ -817,7 +817,7 @@
 	{
 		switch(uType) {
 		  case STRRET_WSTR:
-			wcscpyn(b, UNION_MEMBER(pOleStr), l);
+			lstrcpynW(b, UNION_MEMBER(pOleStr), l);
 			break;
 
 		  case STRRET_OFFSET:

Modified: trunk/reactos/subsys/system/explorer/utility/utility.h
--- trunk/reactos/subsys/system/explorer/utility/utility.h	2005-09-12 20:07:29 UTC (rev 17824)
+++ trunk/reactos/subsys/system/explorer/utility/utility.h	2005-09-12 21:46:09 UTC (rev 17825)
@@ -804,7 +804,7 @@
 		TCHAR b[BUFFER_LEN];
 
[truncated at 1000 lines; 86 more skipped]