diff --git a/.gitignore b/.gitignore index 83226d8..f3ff31b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,8 @@ bin .gradle .settings build +<<<<<<< HEAD +/cpp/pipe/Release/src +======= src +>>>>>>> 1b005c69f5ba5b443ef5addc6aad13236196f3dc diff --git a/cpp/pipe/.cproject b/cpp/pipe/.cproject new file mode 100644 index 0000000..612ccc7 --- /dev/null +++ b/cpp/pipe/.cproject @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/pipe/.project b/cpp/pipe/.project new file mode 100644 index 0000000..a14c5b2 --- /dev/null +++ b/cpp/pipe/.project @@ -0,0 +1,27 @@ + + + cpp.pipe + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/cpp/pipe/Debug/copy.bat b/cpp/pipe/Debug/copy.bat new file mode 100644 index 0000000..2f38e77 --- /dev/null +++ b/cpp/pipe/Debug/copy.bat @@ -0,0 +1 @@ +copy pipe.dll ..\..\..\java\sound\pipe.dll \ No newline at end of file diff --git a/cpp/pipe/Release/copy.bat b/cpp/pipe/Release/copy.bat new file mode 100644 index 0000000..2f38e77 --- /dev/null +++ b/cpp/pipe/Release/copy.bat @@ -0,0 +1 @@ +copy pipe.dll ..\..\..\java\sound\pipe.dll \ No newline at end of file diff --git a/cpp/pipe/Release/pipe.dll b/cpp/pipe/Release/pipe.dll new file mode 100644 index 0000000..c698219 Binary files /dev/null and b/cpp/pipe/Release/pipe.dll differ diff --git a/cpp/pipe/include/strsafe.h b/cpp/pipe/include/strsafe.h new file mode 100644 index 0000000..061b3c4 --- /dev/null +++ b/cpp/pipe/include/strsafe.h @@ -0,0 +1,6611 @@ +/****************************************************************** +* * +* strsafe.h -- This module defines safer C library string * +* routine replacements. These are meant to make C * +* a bit more safe in reference to security and * +* robustness * +* * +* Copyright (c) Microsoft Corp. All rights reserved. * +* * +******************************************************************/ +#ifndef _STRSAFE_H_INCLUDED_ +#define _STRSAFE_H_INCLUDED_ +#pragma once + +#include // for _vsnprintf, _vsnwprintf, getc, getwc +#include // for memset +#include // for va_start, etc. + + +#ifndef _SIZE_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 size_t; +#else +typedef __w64 unsigned int size_t; +#endif // !_WIN64 +#define _SIZE_T_DEFINED +#endif // !_SIZE_T_DEFINED + +#if !defined(_WCHAR_T_DEFINED) && !defined(_NATIVE_WCHAR_T_DEFINED) +typedef unsigned short wchar_t; +#define _WCHAR_T_DEFINED +#endif + +#ifndef _HRESULT_DEFINED +#define _HRESULT_DEFINED +typedef long HRESULT; +#endif // !_HRESULT_DEFINED + +#ifndef SUCCEEDED +#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0) +#endif + +#ifndef FAILED +#define FAILED(hr) ((HRESULT)(hr) < 0) +#endif + +#ifndef S_OK +#define S_OK ((HRESULT)0x00000000L) +#endif + +#ifdef __cplusplus +#define _STRSAFE_EXTERN_C extern "C" +#else +#define _STRSAFE_EXTERN_C extern +#endif + +// If you do not want to use these functions inline (and instead want to link w/ strsafe.lib), then +// #define STRSAFE_LIB before including this header file. +#if defined(STRSAFE_LIB) +#define STRSAFEAPI _STRSAFE_EXTERN_C HRESULT __stdcall +#pragma comment(lib, "strsafe.lib") +#elif defined(STRSAFE_LIB_IMPL) +#define STRSAFEAPI _STRSAFE_EXTERN_C HRESULT __stdcall +#else +#define STRSAFEAPI __inline HRESULT __stdcall +#define STRSAFE_INLINE +#endif + +// Some functions always run inline because they use stdin and we want to avoid building multiple +// versions of strsafe lib depending on if you use msvcrt, libcmt, etc. +#define STRSAFE_INLINE_API __inline HRESULT __stdcall + +// The user can request no "Cb" or no "Cch" fuctions, but not both! +#if defined(STRSAFE_NO_CB_FUNCTIONS) && defined(STRSAFE_NO_CCH_FUNCTIONS) +#error cannot specify both STRSAFE_NO_CB_FUNCTIONS and STRSAFE_NO_CCH_FUNCTIONS !! +#endif + +// This should only be defined when we are building strsafe.lib +#ifdef STRSAFE_LIB_IMPL +#define STRSAFE_INLINE +#endif + + +// If both strsafe.h and ntstrsafe.h are included, only use definitions from one. +#ifndef _NTSTRSAFE_H_INCLUDED_ + +#define STRSAFE_MAX_CCH 2147483647 // max # of characters we support (same as INT_MAX) + +// Flags for controling the Ex functions +// +// STRSAFE_FILL_BYTE(0xFF) 0x000000FF // bottom byte specifies fill pattern +#define STRSAFE_IGNORE_NULLS 0x00000100 // treat null as TEXT("") -- don't fault on NULL buffers +#define STRSAFE_FILL_BEHIND_NULL 0x00000200 // fill in extra space behind the null terminator +#define STRSAFE_FILL_ON_FAILURE 0x00000400 // on failure, overwrite pszDest with fill pattern and null terminate it +#define STRSAFE_NULL_ON_FAILURE 0x00000800 // on failure, set *pszDest = TEXT('\0') +#define STRSAFE_NO_TRUNCATION 0x00001000 // instead of returning a truncated result, copy/append nothing to pszDest and null terminate it + +#define STRSAFE_VALID_FLAGS (0x000000FF | STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND_NULL | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION) + +// helper macro to set the fill character and specify buffer filling +#define STRSAFE_FILL_BYTE(x) ((unsigned long)((x & 0x000000FF) | STRSAFE_FILL_BEHIND_NULL)) +#define STRSAFE_FAILURE_BYTE(x) ((unsigned long)((x & 0x000000FF) | STRSAFE_FILL_ON_FAILURE)) + +#define STRSAFE_GET_FILL_PATTERN(dwFlags) ((int)(dwFlags & 0x000000FF)) + +#endif // _NTSTRSAFE_H_INCLUDED_ + +// STRSAFE error return codes +// +#define STRSAFE_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL) // 0x7A = 122L = ERROR_INSUFFICIENT_BUFFER +#define STRSAFE_E_INVALID_PARAMETER ((HRESULT)0x80070057L) // 0x57 = 87L = ERROR_INVALID_PARAMETER +#define STRSAFE_E_END_OF_FILE ((HRESULT)0x80070026L) // 0x26 = 38L = ERROR_HANDLE_EOF + +// prototypes for the worker functions +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCopyWorkerA(char* pszDest, size_t cchDest, const char* pszSrc); +STRSAFEAPI StringCopyWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc); +STRSAFEAPI StringCopyExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFEAPI StringCopyExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFEAPI StringCopyNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc); +STRSAFEAPI StringCopyNWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc); +STRSAFEAPI StringCopyNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFEAPI StringCopyNExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, size_t cchSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFEAPI StringCatWorkerA(char* pszDest, size_t cchDest, const char* pszSrc); +STRSAFEAPI StringCatWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc); +STRSAFEAPI StringCatExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFEAPI StringCatExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFEAPI StringCatNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend); +STRSAFEAPI StringCatNWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend); +STRSAFEAPI StringCatNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFEAPI StringCatNExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, size_t cchMaxAppend, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFEAPI StringVPrintfWorkerA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList); +STRSAFEAPI StringVPrintfWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, va_list argList); +STRSAFEAPI StringVPrintfExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList); +STRSAFEAPI StringVPrintfExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList); +STRSAFEAPI StringLengthWorkerA(const char* psz, size_t cchMax, size_t* pcch); +STRSAFEAPI StringLengthWorkerW(const wchar_t* psz, size_t cchMax, size_t* pcch); +#endif // STRSAFE_INLINE + +#ifndef STRSAFE_LIB_IMPL +// these functions are always inline +STRSAFE_INLINE_API StringGetsExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFE_INLINE_API StringGetsExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +#endif + +#ifdef _NTSTRSAFE_H_INCLUDED_ +#pragma warning(push) +#pragma warning(disable : 4995) +#endif // _NTSTRSAFE_H_INCLUDED_ + + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchCopy( + OUT LPTSTR pszDest, + IN size_t cchDest, + IN LPCTSTR pszSrc + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcpy'. + The size of the destination buffer (in characters) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This routine is not a replacement for strncpy. That function will pad the + destination string with extra null termination characters if the count is + greater than the length of the source string, and it will fail to null + terminate the destination string if the source string length is greater + than or equal to the count. You can not blindly use this instead of strncpy: + it is common for code to use it to "patch" strings and you would introduce + errors if the code started null terminating in the middle of the string. + + This function returns a hresult, and not a pointer. It returns + S_OK if the string was copied without truncation and null terminated, + otherwise it will return a failure code. In failure cases as much of + pszSrc will be copied to pszDest as possible, and pszDest will be null + terminated. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be = (_tcslen(src) + 1) to hold all of the + source including the null terminator + + pszSrc - source string which must be null terminated + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See StringCchCopyEx if you require + the handling of NULL values. + +Return Value: + + S_OK - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function. + +--*/ + +STRSAFEAPI StringCchCopyA(char* pszDest, size_t cchDest, const char* pszSrc); +STRSAFEAPI StringCchCopyW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc); +#ifdef UNICODE +#define StringCchCopy StringCchCopyW +#else +#define StringCchCopy StringCchCopyA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCchCopyA(char* pszDest, size_t cchDest, const char* pszSrc) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCopyWorkerA(pszDest, cchDest, pszSrc); + } + + return hr; +} + +STRSAFEAPI StringCchCopyW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCopyWorkerW(pszDest, cchDest, pszSrc); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CCH_FUNCTIONS + + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbCopy( + OUT LPTSTR pszDest, + IN size_t cbDest, + IN LPCTSTR pszSrc + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcpy'. + The size of the destination buffer (in bytes) is a parameter and this + function will not write past the end of this buffer and it will ALWAYS + null terminate the destination buffer (unless it is zero length). + + This routine is not a replacement for strncpy. That function will pad the + destination string with extra null termination characters if the count is + greater than the length of the source string, and it will fail to null + terminate the destination string if the source string length is greater + than or equal to the count. You can not blindly use this instead of strncpy: + it is common for code to use it to "patch" strings and you would introduce + errors if the code started null terminating in the middle of the string. + + This function returns a hresult, and not a pointer. It returns + S_OK if the string was copied without truncation and null terminated, + otherwise it will return a failure code. In failure cases as much of pszSrc + will be copied to pszDest as possible, and pszDest will be null terminated. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + length must be = ((_tcslen(src) + 1) * sizeof(TCHAR)) to + hold all of the source including the null terminator + + pszSrc - source string which must be null terminated + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See StringCbCopyEx if you require + the handling of NULL values. + +Return Value: + + S_OK - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function. + +--*/ + +STRSAFEAPI StringCbCopyA(char* pszDest, size_t cbDest, const char* pszSrc); +STRSAFEAPI StringCbCopyW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc); +#ifdef UNICODE +#define StringCbCopy StringCbCopyW +#else +#define StringCbCopy StringCbCopyA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCbCopyA(char* pszDest, size_t cbDest, const char* pszSrc) +{ + HRESULT hr; + size_t cchDest; + + // convert to count of characters + cchDest = cbDest / sizeof(char); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCopyWorkerA(pszDest, cchDest, pszSrc); + } + + return hr; +} + +STRSAFEAPI StringCbCopyW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc) +{ + HRESULT hr; + size_t cchDest; + + // convert to count of characters + cchDest = cbDest / sizeof(wchar_t); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCopyWorkerW(pszDest, cchDest, pszSrc); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CB_FUNCTIONS + + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchCopyEx( + OUT LPTSTR pszDest OPTIONAL, + IN size_t cchDest, + IN LPCTSTR pszSrc OPTIONAL, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcchRemaining OPTIONAL, + IN DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcpy' with + some additional parameters. In addition to functionality provided by + StringCchCopy, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be = (_tcslen(pszSrc) + 1) to hold all of + the source including the null terminator + + pszSrc - source string which must be null terminated + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function copied any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return the + number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STRSAFE_E_INSUFFICIENT_BUFFER + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + S_OK - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCchCopyExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFEAPI StringCchCopyExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +#ifdef UNICODE +#define StringCchCopyEx StringCchCopyExW +#else +#define StringCchCopyEx StringCchCopyExA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCchCopyExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + + hr = StringCopyExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); + } + + return hr; +} + +STRSAFEAPI StringCchCopyExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + hr = StringCopyExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CCH_FUNCTIONS + + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbCopyEx( + OUT LPTSTR pszDest OPTIONAL, + IN size_t cbDest, + IN LPCTSTR pszSrc OPTIONAL, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcbRemaining OPTIONAL, + IN DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcpy' with + some additional parameters. In addition to functionality provided by + StringCbCopy, this routine also returns a pointer to the end of the + destination string and the number of bytes left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + length must be ((_tcslen(pszSrc) + 1) * sizeof(TCHAR)) to + hold all of the source including the null terminator + + pszSrc - source string which must be null terminated + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function copied any data, the result will point to the + null termination character + + pcbRemaining - pcbRemaining is non-null,the function will return the + number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STRSAFE_E_INSUFFICIENT_BUFFER + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + S_OK - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCbCopyExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); +STRSAFEAPI StringCbCopyExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); +#ifdef UNICODE +#define StringCbCopyEx StringCbCopyExW +#else +#define StringCbCopyEx StringCbCopyExA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCbCopyExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) +{ + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(char); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCopyExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags); + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + } + } + + return hr; +} + +STRSAFEAPI StringCbCopyExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) +{ + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(wchar_t); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCopyExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags); + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CB_FUNCTIONS + + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchCopyN( + OUT LPTSTR pszDest, + IN size_t cchDest, + IN LPCTSTR pszSrc, + IN size_t cchSrc + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy'. + The size of the destination buffer (in characters) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This routine is meant as a replacement for strncpy, but it does behave + differently. This function will not pad the destination buffer with extra + null termination characters if cchSrc is greater than the length of pszSrc. + + This function returns a hresult, and not a pointer. It returns + S_OK if the entire string or the first cchSrc characters were copied + without truncation and the resultant destination string was null terminated, + otherwise it will return a failure code. In failure cases as much of pszSrc + will be copied to pszDest as possible, and pszDest will be null terminated. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be = (_tcslen(src) + 1) to hold all of the + source including the null terminator + + pszSrc - source string + + cchSrc - maximum number of characters to copy from source string, + not including the null terminator. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See StringCchCopyNEx if you require + the handling of NULL values. + +Return Value: + + S_OK - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function. + +--*/ + +STRSAFEAPI StringCchCopyNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc); +STRSAFEAPI StringCchCopyNW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc); +#ifdef UNICODE +#define StringCchCopyN StringCchCopyNW +#else +#define StringCchCopyN StringCchCopyNA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCchCopyNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc) +{ + HRESULT hr; + + if ((cchDest > STRSAFE_MAX_CCH) || + (cchSrc > STRSAFE_MAX_CCH)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCopyNWorkerA(pszDest, cchDest, pszSrc, cchSrc); + } + + return hr; +} + +STRSAFEAPI StringCchCopyNW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc) +{ + HRESULT hr; + + if ((cchDest > STRSAFE_MAX_CCH) || + (cchSrc > STRSAFE_MAX_CCH)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCopyNWorkerW(pszDest, cchDest, pszSrc, cchSrc); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CCH_FUNCTIONS + + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbCopyN( + OUT LPTSTR pszDest, + IN size_t cbDest, + IN LPCTSTR pszSrc, + IN size_t cbSrc + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy'. + The size of the destination buffer (in bytes) is a parameter and this + function will not write past the end of this buffer and it will ALWAYS + null terminate the destination buffer (unless it is zero length). + + This routine is meant as a replacement for strncpy, but it does behave + differently. This function will not pad the destination buffer with extra + null termination characters if cbSrc is greater than the size of pszSrc. + + This function returns a hresult, and not a pointer. It returns + S_OK if the entire string or the first cbSrc characters were + copied without truncation and the resultant destination string was null + terminated, otherwise it will return a failure code. In failure cases as + much of pszSrc will be copied to pszDest as possible, and pszDest will be + null terminated. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + length must be = ((_tcslen(src) + 1) * sizeof(TCHAR)) to + hold all of the source including the null terminator + + pszSrc - source string + + cbSrc - maximum number of bytes to copy from source string, + not including the null terminator. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See StringCbCopyEx if you require + the handling of NULL values. + +Return Value: + + S_OK - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function. + +--*/ + +STRSAFEAPI StringCbCopyNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbSrc); +STRSAFEAPI StringCbCopyNW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbSrc); +#ifdef UNICODE +#define StringCbCopyN StringCbCopyNW +#else +#define StringCbCopyN StringCbCopyNA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCbCopyNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbSrc) +{ + HRESULT hr; + size_t cchDest; + size_t cchSrc; + + // convert to count of characters + cchDest = cbDest / sizeof(char); + cchSrc = cbSrc / sizeof(char); + + if ((cchDest > STRSAFE_MAX_CCH) || + (cchSrc > STRSAFE_MAX_CCH)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCopyNWorkerA(pszDest, cchDest, pszSrc, cchSrc); + } + + return hr; +} + +STRSAFEAPI StringCbCopyNW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbSrc) +{ + HRESULT hr; + size_t cchDest; + size_t cchSrc; + + // convert to count of characters + cchDest = cbDest / sizeof(wchar_t); + cchSrc = cbSrc / sizeof(wchar_t); + + if ((cchDest > STRSAFE_MAX_CCH) || + (cchSrc > STRSAFE_MAX_CCH)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCopyNWorkerW(pszDest, cchDest, pszSrc, cchSrc); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CB_FUNCTIONS + + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchCopyNEx( + OUT LPTSTR pszDest OPTIONAL, + IN size_t cchDest, + IN LPCTSTR pszSrc OPTIONAL, + IN size_t cchSrc, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcchRemaining OPTIONAL, + IN DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy' with + some additional parameters. In addition to functionality provided by + StringCchCopyN, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination + string including the null terminator. The flags parameter allows + additional controls. + + This routine is meant as a replacement for strncpy, but it does behave + differently. This function will not pad the destination buffer with extra + null termination characters if cchSrc is greater than the length of pszSrc. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be = (_tcslen(pszSrc) + 1) to hold all of + the source including the null terminator + + pszSrc - source string + + cchSrc - maximum number of characters to copy from the source + string + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function copied any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return the + number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STRSAFE_E_INSUFFICIENT_BUFFER + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + S_OK - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCchCopyNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFEAPI StringCchCopyNExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +#ifdef UNICODE +#define StringCchCopyNEx StringCchCopyNExW +#else +#define StringCchCopyNEx StringCchCopyNExA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCchCopyNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr; + + if ((cchDest > STRSAFE_MAX_CCH) || + (cchSrc > STRSAFE_MAX_CCH)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + + hr = StringCopyNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, pcchRemaining, dwFlags); + } + + return hr; +} + +STRSAFEAPI StringCchCopyNExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr; + + if ((cchDest > STRSAFE_MAX_CCH) || + (cchSrc > STRSAFE_MAX_CCH)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + hr = StringCopyNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, pcchRemaining, dwFlags); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CCH_FUNCTIONS + + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbCopyNEx( + OUT LPTSTR pszDest OPTIONAL, + IN size_t cbDest, + IN LPCTSTR pszSrc OPTIONAL, + IN size_t cbSrc, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcbRemaining OPTIONAL, + IN DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy' with + some additional parameters. In addition to functionality provided by + StringCbCopyN, this routine also returns a pointer to the end of the + destination string and the number of bytes left in the destination string + including the null terminator. The flags parameter allows additional controls. + + This routine is meant as a replacement for strncpy, but it does behave + differently. This function will not pad the destination buffer with extra + null termination characters if cbSrc is greater than the size of pszSrc. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + length must be ((_tcslen(pszSrc) + 1) * sizeof(TCHAR)) to + hold all of the source including the null terminator + + pszSrc - source string + + cbSrc - maximum number of bytes to copy from source string + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function copied any data, the result will point to the + null termination character + + pcbRemaining - pcbRemaining is non-null,the function will return the + number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STRSAFE_E_INSUFFICIENT_BUFFER + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + S_OK - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCbCopyNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); +STRSAFEAPI StringCbCopyNExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); +#ifdef UNICODE +#define StringCbCopyNEx StringCbCopyNExW +#else +#define StringCbCopyNEx StringCbCopyNExA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCbCopyNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) +{ + HRESULT hr; + size_t cchDest; + size_t cchSrc; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(char); + cchSrc = cbSrc / sizeof(char); + + if ((cchDest > STRSAFE_MAX_CCH) || + (cchSrc > STRSAFE_MAX_CCH)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCopyNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, &cchRemaining, dwFlags); + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + } + } + + return hr; +} + +STRSAFEAPI StringCbCopyNExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) +{ + HRESULT hr; + size_t cchDest; + size_t cchSrc; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(wchar_t); + cchSrc = cbSrc / sizeof(wchar_t); + + if ((cchDest > STRSAFE_MAX_CCH) || + (cchSrc > STRSAFE_MAX_CCH)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCopyNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, &cchRemaining, dwFlags); + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CB_FUNCTIONS + + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchCat( + IN OUT LPTSTR pszDest, + IN size_t cchDest, + IN LPCTSTR pszSrc + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcat'. + The size of the destination buffer (in characters) is a parameter and this + function will not write past the end of this buffer and it will ALWAYS + null terminate the destination buffer (unless it is zero length). + + This function returns a hresult, and not a pointer. It returns + S_OK if the string was concatenated without truncation and null terminated, + otherwise it will return a failure code. In failure cases as much of pszSrc + will be appended to pszDest as possible, and pszDest will be null + terminated. + +Arguments: + + pszDest - destination string which must be null terminated + + cchDest - size of destination buffer in characters. + length must be = (_tcslen(pszDest) + _tcslen(pszSrc) + 1) + to hold all of the combine string plus the null + terminator + + pszSrc - source string which must be null terminated + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See StringCchCatEx if you require + the handling of NULL values. + +Return Value: + + S_OK - if there was source data and it was all concatenated and + the resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the operation + failed due to insufficient space. When this error occurs, + the destination buffer is modified to contain a truncated + version of the ideal result and is null terminated. This + is useful for situations where truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCchCatA(char* pszDest, size_t cchDest, const char* pszSrc); +STRSAFEAPI StringCchCatW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc); +#ifdef UNICODE +#define StringCchCat StringCchCatW +#else +#define StringCchCat StringCchCatA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCchCatA(char* pszDest, size_t cchDest, const char* pszSrc) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCatWorkerA(pszDest, cchDest, pszSrc); + } + + return hr; +} + +STRSAFEAPI StringCchCatW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCatWorkerW(pszDest, cchDest, pszSrc); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CCH_FUNCTIONS + + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbCat( + IN OUT LPTSTR pszDest, + IN size_t cbDest, + IN LPCTSTR pszSrc + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcat'. + The size of the destination buffer (in bytes) is a parameter and this + function will not write past the end of this buffer and it will ALWAYS + null terminate the destination buffer (unless it is zero length). + + This function returns a hresult, and not a pointer. It returns + S_OK if the string was concatenated without truncation and null terminated, + otherwise it will return a failure code. In failure cases as much of pszSrc + will be appended to pszDest as possible, and pszDest will be null + terminated. + +Arguments: + + pszDest - destination string which must be null terminated + + cbDest - size of destination buffer in bytes. + length must be = ((_tcslen(pszDest) + _tcslen(pszSrc) + 1) * sizeof(TCHAR) + to hold all of the combine string plus the null + terminator + + pszSrc - source string which must be null terminated + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See StringCbCatEx if you require + the handling of NULL values. + +Return Value: + + S_OK - if there was source data and it was all concatenated and + the resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the operation + failed due to insufficient space. When this error occurs, + the destination buffer is modified to contain a truncated + version of the ideal result and is null terminated. This + is useful for situations where truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCbCatA(char* pszDest, size_t cbDest, const char* pszSrc); +STRSAFEAPI StringCbCatW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc); +#ifdef UNICODE +#define StringCbCat StringCbCatW +#else +#define StringCbCat StringCbCatA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCbCatA(char* pszDest, size_t cbDest, const char* pszSrc) +{ + HRESULT hr; + size_t cchDest; + + cchDest = cbDest / sizeof(char); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCatWorkerA(pszDest, cchDest, pszSrc); + } + + return hr; +} + +STRSAFEAPI StringCbCatW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc) +{ + HRESULT hr; + size_t cchDest; + + cchDest = cbDest / sizeof(wchar_t); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCatWorkerW(pszDest, cchDest, pszSrc); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CB_FUNCTIONS + + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchCatEx( + IN OUT LPTSTR pszDest OPTIONAL, + IN size_t cchDest, + IN LPCTSTR pszSrc OPTIONAL, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcchRemaining OPTIONAL, + IN DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcat' with + some additional parameters. In addition to functionality provided by + StringCchCat, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string which must be null terminated + + cchDest - size of destination buffer in characters + length must be (_tcslen(pszDest) + _tcslen(pszSrc) + 1) + to hold all of the combine string plus the null + terminator. + + pszSrc - source string which must be null terminated + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function appended any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return the + number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcat + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any pre-existing + or truncated string + + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any pre-existing or + truncated string + + STRSAFE_NO_TRUNCATION + if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + S_OK - if there was source data and it was all concatenated and + the resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the operation + failed due to insufficient space. When this error + occurs, the destination buffer is modified to contain + a truncated version of the ideal result and is null + terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCchCatExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFEAPI StringCchCatExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +#ifdef UNICODE +#define StringCchCatEx StringCchCatExW +#else +#define StringCchCatEx StringCchCatExA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCchCatExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + + hr = StringCatExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); + } + + return hr; +} + +STRSAFEAPI StringCchCatExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + hr = StringCatExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CCH_FUNCTIONS + + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbCatEx( + IN OUT LPTSTR pszDest OPTIONAL, + IN size_t cbDest, + IN LPCTSTR pszSrc OPTIONAL, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcbRemaining OPTIONAL, + IN DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcat' with + some additional parameters. In addition to functionality provided by + StringCbCat, this routine also returns a pointer to the end of the + destination string and the number of bytes left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string which must be null terminated + + cbDest - size of destination buffer in bytes. + length must be ((_tcslen(pszDest) + _tcslen(pszSrc) + 1) * sizeof(TCHAR) + to hold all of the combine string plus the null + terminator. + + pszSrc - source string which must be null terminated + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function appended any data, the result will point to the + null termination character + + pcbRemaining - if pcbRemaining is non-null, the function will return + the number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcat + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any pre-existing + or truncated string + + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any pre-existing or + truncated string + + STRSAFE_NO_TRUNCATION + if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + S_OK - if there was source data and it was all concatenated + and the resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the operation + failed due to insufficient space. When this error + occurs, the destination buffer is modified to contain + a truncated version of the ideal result and is null + terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCbCatExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); +STRSAFEAPI StringCbCatExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); +#ifdef UNICODE +#define StringCbCatEx StringCbCatExW +#else +#define StringCbCatEx StringCbCatExA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCbCatExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) +{ + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(char); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCatExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags); + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + } + } + + return hr; +} + +STRSAFEAPI StringCbCatExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) +{ + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(wchar_t); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCatExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags); + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CB_FUNCTIONS + + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchCatN( + IN OUT LPTSTR pszDest, + IN size_t cchDest, + IN LPCTSTR pszSrc, + IN size_t cchMaxAppend + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat'. + The size of the destination buffer (in characters) is a parameter as well as + the maximum number of characters to append, excluding the null terminator. + This function will not write past the end of the destination buffer and it will + ALWAYS null terminate pszDest (unless it is zero length). + + This function returns a hresult, and not a pointer. It returns + S_OK if all of pszSrc or the first cchMaxAppend characters were appended + to the destination string and it was null terminated, otherwise it will + return a failure code. In failure cases as much of pszSrc will be appended + to pszDest as possible, and pszDest will be null terminated. + +Arguments: + + pszDest - destination string which must be null terminated + + cchDest - size of destination buffer in characters. + length must be (_tcslen(pszDest) + min(cchMaxAppend, _tcslen(pszSrc)) + 1) + to hold all of the combine string plus the null + terminator. + + pszSrc - source string + + cchMaxAppend - maximum number of characters to append + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See StringCchCatNEx if you require + the handling of NULL values. + +Return Value: + + S_OK - if all of pszSrc or the first cchMaxAppend characters + were concatenated to pszDest and the resultant dest + string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the operation + failed due to insufficient space. When this error + occurs, the destination buffer is modified to contain + a truncated version of the ideal result and is null + terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCchCatNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend); +STRSAFEAPI StringCchCatNW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend); +#ifdef UNICODE +#define StringCchCatN StringCchCatNW +#else +#define StringCchCatN StringCchCatNA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCchCatNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCatNWorkerA(pszDest, cchDest, pszSrc, cchMaxAppend); + } + + return hr; +} + +STRSAFEAPI StringCchCatNW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringCatNWorkerW(pszDest, cchDest, pszSrc, cchMaxAppend); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CCH_FUNCTIONS + + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbCatN( + IN OUT LPTSTR pszDest, + IN size_t cbDest, + IN LPCTSTR pszSrc, + IN size_t cbMaxAppend + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat'. + The size of the destination buffer (in bytes) is a parameter as well as + the maximum number of bytes to append, excluding the null terminator. + This function will not write past the end of the destination buffer and it will + ALWAYS null terminate pszDest (unless it is zero length). + + This function returns a hresult, and not a pointer. It returns + S_OK if all of pszSrc or the first cbMaxAppend bytes were appended + to the destination string and it was null terminated, otherwise it will + return a failure code. In failure cases as much of pszSrc will be appended + to pszDest as possible, and pszDest will be null terminated. + +Arguments: + + pszDest - destination string which must be null terminated + + cbDest - size of destination buffer in bytes. + length must be ((_tcslen(pszDest) + min(cbMaxAppend / sizeof(TCHAR), _tcslen(pszSrc)) + 1) * sizeof(TCHAR) + to hold all of the combine string plus the null + terminator. + + pszSrc - source string + + cbMaxAppend - maximum number of bytes to append + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See StringCbCatNEx if you require + the handling of NULL values. + +Return Value: + + S_OK - if all of pszSrc or the first cbMaxAppend bytes were + concatenated to pszDest and the resultant dest string + was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the operation + failed due to insufficient space. When this error + occurs, the destination buffer is modified to contain + a truncated version of the ideal result and is null + terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCbCatNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend); +STRSAFEAPI StringCbCatNW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbMaxAppend); +#ifdef UNICODE +#define StringCbCatN StringCbCatNW +#else +#define StringCbCatN StringCbCatNA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCbCatNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend) +{ + HRESULT hr; + size_t cchDest; + + cchDest = cbDest / sizeof(char); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cchMaxAppend; + + cchMaxAppend = cbMaxAppend / sizeof(char); + + hr = StringCatNWorkerA(pszDest, cchDest, pszSrc, cchMaxAppend); + } + + return hr; +} + +STRSAFEAPI StringCbCatNW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbMaxAppend) +{ + HRESULT hr; + size_t cchDest; + + cchDest = cbDest / sizeof(wchar_t); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cchMaxAppend; + + cchMaxAppend = cbMaxAppend / sizeof(wchar_t); + + hr = StringCatNWorkerW(pszDest, cchDest, pszSrc, cchMaxAppend); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CB_FUNCTIONS + + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchCatNEx( + IN OUT LPTSTR pszDest OPTIONAL, + IN size_t cchDest, + IN LPCTSTR pszSrc OPTIONAL, + IN size_t cchMaxAppend, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcchRemaining OPTIONAL, + IN DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat', with + some additional parameters. In addition to functionality provided by + StringCchCatN, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string which must be null terminated + + cchDest - size of destination buffer in characters. + length must be (_tcslen(pszDest) + min(cchMaxAppend, _tcslen(pszSrc)) + 1) + to hold all of the combine string plus the null + terminator. + + pszSrc - source string + + cchMaxAppend - maximum number of characters to append + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function appended any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return the + number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")) + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any pre-existing + or truncated string + + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any pre-existing or + truncated string + + STRSAFE_NO_TRUNCATION + if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + S_OK - if all of pszSrc or the first cchMaxAppend characters + were concatenated to pszDest and the resultant dest + string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the operation + failed due to insufficient space. When this error + occurs, the destination buffer is modified to contain + a truncated version of the ideal result and is null + terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCchCatNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFEAPI StringCchCatNExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +#ifdef UNICODE +#define StringCchCatNEx StringCchCatNExW +#else +#define StringCchCatNEx StringCchCatNExA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCchCatNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + + hr = StringCatNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, pcchRemaining, dwFlags); + } + + return hr; +} + +STRSAFEAPI StringCchCatNExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + hr = StringCatNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, pcchRemaining, dwFlags); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CCH_FUNCTIONS + + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbCatNEx( + IN OUT LPTSTR pszDest OPTIONAL, + IN size_t cbDest, + IN LPCTSTR pszSrc OPTIONAL, + IN size_t cbMaxAppend, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcchRemaining OPTIONAL, + IN DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat', with + some additional parameters. In addition to functionality provided by + StringCbCatN, this routine also returns a pointer to the end of the + destination string and the number of bytes left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string which must be null terminated + + cbDest - size of destination buffer in bytes. + length must be ((_tcslen(pszDest) + min(cbMaxAppend / sizeof(TCHAR), _tcslen(pszSrc)) + 1) * sizeof(TCHAR) + to hold all of the combine string plus the null + terminator. + + pszSrc - source string + + cbMaxAppend - maximum number of bytes to append + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function appended any data, the result will point to the + null termination character + + pcbRemaining - if pcbRemaining is non-null, the function will return the + number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")) + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any pre-existing + or truncated string + + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any pre-existing or + truncated string + + STRSAFE_NO_TRUNCATION + if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + S_OK - if all of pszSrc or the first cbMaxAppend bytes were + concatenated to pszDest and the resultant dest string + was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the operation + failed due to insufficient space. When this error + occurs, the destination buffer is modified to contain + a truncated version of the ideal result and is null + terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCbCatNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); +STRSAFEAPI StringCbCatNExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbMaxAppend, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); +#ifdef UNICODE +#define StringCbCatNEx StringCbCatNExW +#else +#define StringCbCatNEx StringCbCatNExA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCbCatNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) +{ + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(char); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cchMaxAppend; + + cchMaxAppend = cbMaxAppend / sizeof(char); + + hr = StringCatNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, &cchRemaining, dwFlags); + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + } + } + + return hr; +} + +STRSAFEAPI StringCbCatNExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbMaxAppend, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) +{ + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(wchar_t); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cchMaxAppend; + + cchMaxAppend = cbMaxAppend / sizeof(wchar_t); + + hr = StringCatNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, &cchRemaining, dwFlags); + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CB_FUNCTIONS + + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchVPrintf( + OUT LPTSTR pszDest, + IN size_t cchDest, + IN LPCTSTR pszFormat, + IN va_list argList + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'vsprintf'. + The size of the destination buffer (in characters) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This function returns a hresult, and not a pointer. It returns + S_OK if the string was printed without truncation and null terminated, + otherwise it will return a failure code. In failure cases it will return + a truncated version of the ideal result. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters + length must be sufficient to hold the resulting formatted + string, including the null terminator. + + pszFormat - format string which must be null terminated + + argList - va_list from the variable arguments according to the + stdarg.h convention + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL. See StringCchVPrintfEx if you + require the handling of NULL values. + +Return Value: + + S_OK - if there was sufficient space in the dest buffer for + the resultant string and it was null terminated. + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCchVPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList); +STRSAFEAPI StringCchVPrintfW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, va_list argList); +#ifdef UNICODE +#define StringCchVPrintf StringCchVPrintfW +#else +#define StringCchVPrintf StringCchVPrintfA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCchVPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList); + } + + return hr; +} + +STRSAFEAPI StringCchVPrintfW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, va_list argList) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CCH_FUNCTIONS + + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbVPrintf( + OUT LPTSTR pszDest, + IN size_t cbDest, + IN LPCTSTR pszFormat, + IN va_list argList + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'vsprintf'. + The size of the destination buffer (in bytes) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This function returns a hresult, and not a pointer. It returns + S_OK if the string was printed without truncation and null terminated, + otherwise it will return a failure code. In failure cases it will return + a truncated version of the ideal result. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes + length must be sufficient to hold the resulting formatted + string, including the null terminator. + + pszFormat - format string which must be null terminated + + argList - va_list from the variable arguments according to the + stdarg.h convention + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL. See StringCbVPrintfEx if you + require the handling of NULL values. + + +Return Value: + + S_OK - if there was sufficient space in the dest buffer for + the resultant string and it was null terminated. + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCbVPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, va_list argList); +STRSAFEAPI StringCbVPrintfW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszFormat, va_list argList); +#ifdef UNICODE +#define StringCbVPrintf StringCbVPrintfW +#else +#define StringCbVPrintf StringCbVPrintfA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCbVPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, va_list argList) +{ + HRESULT hr; + size_t cchDest; + + cchDest = cbDest / sizeof(char); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList); + } + + return hr; +} + +STRSAFEAPI StringCbVPrintfW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszFormat, va_list argList) +{ + HRESULT hr; + size_t cchDest; + + cchDest = cbDest / sizeof(wchar_t); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CB_FUNCTIONS + + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchPrintf( + OUT LPTSTR pszDest, + IN size_t cchDest, + IN LPCTSTR pszFormat, + ... + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'sprintf'. + The size of the destination buffer (in characters) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This function returns a hresult, and not a pointer. It returns + S_OK if the string was printed without truncation and null terminated, + otherwise it will return a failure code. In failure cases it will return + a truncated version of the ideal result. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters + length must be sufficient to hold the resulting formatted + string, including the null terminator. + + pszFormat - format string which must be null terminated + + ... - additional parameters to be formatted according to + the format string + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL. See StringCchPrintfEx if you + require the handling of NULL values. + +Return Value: + + S_OK - if there was sufficient space in the dest buffer for + the resultant string and it was null terminated. + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCchPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, ...); +STRSAFEAPI StringCchPrintfW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, ...); +#ifdef UNICODE +#define StringCchPrintf StringCchPrintfW +#else +#define StringCchPrintf StringCchPrintfA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCchPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, ...) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + va_list argList; + + va_start(argList, pszFormat); + + hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList); + + va_end(argList); + } + + return hr; +} + +STRSAFEAPI StringCchPrintfW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, ...) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + va_list argList; + + va_start(argList, pszFormat); + + hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList); + + va_end(argList); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CCH_FUNCTIONS + + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbPrintf( + OUT LPTSTR pszDest, + IN size_t cbDest, + IN LPCTSTR pszFormat, + ... + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'sprintf'. + The size of the destination buffer (in bytes) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This function returns a hresult, and not a pointer. It returns + S_OK if the string was printed without truncation and null terminated, + otherwise it will return a failure code. In failure cases it will return + a truncated version of the ideal result. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes + length must be sufficient to hold the resulting formatted + string, including the null terminator. + + pszFormat - format string which must be null terminated + + ... - additional parameters to be formatted according to + the format string + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL. See StringCbPrintfEx if you + require the handling of NULL values. + + +Return Value: + + S_OK - if there was sufficient space in the dest buffer for + the resultant string and it was null terminated. + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCbPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, ...); +STRSAFEAPI StringCbPrintfW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszFormat, ...); +#ifdef UNICODE +#define StringCbPrintf StringCbPrintfW +#else +#define StringCbPrintf StringCbPrintfA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCbPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, ...) +{ + HRESULT hr; + size_t cchDest; + + cchDest = cbDest / sizeof(char); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + va_list argList; + + va_start(argList, pszFormat); + + hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList); + + va_end(argList); + } + + return hr; +} + +STRSAFEAPI StringCbPrintfW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszFormat, ...) +{ + HRESULT hr; + size_t cchDest; + + cchDest = cbDest / sizeof(wchar_t); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + va_list argList; + + va_start(argList, pszFormat); + + hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList); + + va_end(argList); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CB_FUNCTIONS + + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchPrintfEx( + OUT LPTSTR pszDest OPTIONAL, + IN size_t cchDest, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcchRemaining OPTIONAL, + IN DWORD dwFlags, + IN LPCTSTR pszFormat OPTIONAL, + ... + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'sprintf' with + some additional parameters. In addition to functionality provided by + StringCchPrintf, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be sufficient to contain the resulting + formatted string plus the null terminator. + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function printed any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return + the number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")) + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STRSAFE_E_INSUFFICIENT_BUFFER + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. + + pszFormat - format string which must be null terminated + + ... - additional parameters to be formatted according to + the format string + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS + flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and + pszFormat may be NULL. An error may still be returned even though NULLS + are ignored due to insufficient space. + +Return Value: + + S_OK - if there was source data and it was all concatenated and + the resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCchPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, ...); +STRSAFEAPI StringCchPrintfExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, ...); +#ifdef UNICODE +#define StringCchPrintfEx StringCchPrintfExW +#else +#define StringCchPrintfEx StringCchPrintfExA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCchPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, ...) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + va_list argList; + + // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + va_start(argList, pszFormat); + + hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList); + + va_end(argList); + } + + return hr; +} + +STRSAFEAPI StringCchPrintfExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, ...) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + va_list argList; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + va_start(argList, pszFormat); + + hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList); + + va_end(argList); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CCH_FUNCTIONS + + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbPrintfEx( + OUT LPTSTR pszDest OPTIONAL, + IN size_t cbDest, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcbRemaining OPTIONAL, + IN DWORD dwFlags, + IN LPCTSTR pszFormat OPTIONAL, + ... + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'sprintf' with + some additional parameters. In addition to functionality provided by + StringCbPrintf, this routine also returns a pointer to the end of the + destination string and the number of bytes left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + length must be sufficient to contain the resulting + formatted string plus the null terminator. + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function printed any data, the result will point to the + null termination character + + pcbRemaining - if pcbRemaining is non-null, the function will return + the number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")) + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STRSAFE_E_INSUFFICIENT_BUFFER + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. + + pszFormat - format string which must be null terminated + + ... - additional parameters to be formatted according to + the format string + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS + flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and + pszFormat may be NULL. An error may still be returned even though NULLS + are ignored due to insufficient space. + +Return Value: + + S_OK - if there was source data and it was all concatenated and + the resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCbPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, ...); +STRSAFEAPI StringCbPrintfExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const wchar_t* pszFormat, ...); +#ifdef UNICODE +#define StringCbPrintfEx StringCbPrintfExW +#else +#define StringCbPrintfEx StringCbPrintfExA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCbPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, ...) +{ + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(char); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + va_list argList; + + va_start(argList, pszFormat); + + hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList); + + va_end(argList); + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + } + } + + return hr; +} + +STRSAFEAPI StringCbPrintfExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const wchar_t* pszFormat, ...) +{ + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(wchar_t); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + va_list argList; + + va_start(argList, pszFormat); + + hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList); + + va_end(argList); + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CB_FUNCTIONS + + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchVPrintfEx( + OUT LPTSTR pszDest OPTIONAL, + IN size_t cchDest, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcchRemaining OPTIONAL, + IN DWORD dwFlags, + IN LPCTSTR pszFormat OPTIONAL, + IN va_list argList + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'vsprintf' with + some additional parameters. In addition to functionality provided by + StringCchVPrintf, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be sufficient to contain the resulting + formatted string plus the null terminator. + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function printed any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return + the number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")) + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STRSAFE_E_INSUFFICIENT_BUFFER + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. + + pszFormat - format string which must be null terminated + + argList - va_list from the variable arguments according to the + stdarg.h convention + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS + flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and + pszFormat may be NULL. An error may still be returned even though NULLS + are ignored due to insufficient space. + +Return Value: + + S_OK - if there was source data and it was all concatenated and + the resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCchVPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList); +STRSAFEAPI StringCchVPrintfExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList); +#ifdef UNICODE +#define StringCchVPrintfEx StringCchVPrintfExW +#else +#define StringCchVPrintfEx StringCchVPrintfExA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCchVPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + + hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList); + } + + return hr; +} + +STRSAFEAPI StringCchVPrintfExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CCH_FUNCTIONS + + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbVPrintfEx( + OUT LPTSTR pszDest OPTIONAL, + IN size_t cbDest, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcbRemaining OPTIONAL, + IN DWORD dwFlags, + IN LPCTSTR pszFormat OPTIONAL, + IN va_list argList + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'vsprintf' with + some additional parameters. In addition to functionality provided by + StringCbVPrintf, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + length must be sufficient to contain the resulting + formatted string plus the null terminator. + + ppszDestEnd - if ppszDestEnd is non-null, the function will return + a pointer to the end of the destination string. If the + function printed any data, the result will point to the + null termination character + + pcbRemaining - if pcbRemaining is non-null, the function will return + the number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")) + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STRSAFE_E_INSUFFICIENT_BUFFER + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. + + pszFormat - format string which must be null terminated + + argList - va_list from the variable arguments according to the + stdarg.h convention + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS + flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and + pszFormat may be NULL. An error may still be returned even though NULLS + are ignored due to insufficient space. + +Return Value: + + S_OK - if there was source data and it was all concatenated and + the resultant dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function + +--*/ + +STRSAFEAPI StringCbVPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList); +STRSAFEAPI StringCbVPrintfExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList); +#ifdef UNICODE +#define StringCbVPrintfEx StringCbVPrintfExW +#else +#define StringCbVPrintfEx StringCbVPrintfExA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCbVPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList) +{ + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(char); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList); + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + } + } + + return hr; +} + +STRSAFEAPI StringCbVPrintfExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList) +{ + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(wchar_t); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList); + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CB_FUNCTIONS + + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchGets( + OUT LPTSTR pszDest, + IN size_t cchDest + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'gets'. + The size of the destination buffer (in characters) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This routine is not a replacement for fgets. That function does not replace + newline characters with a null terminator. + + This function returns a hresult, and not a pointer. It returns + S_OK if any characters were read from stdin and copied to pszDest and + pszDest was null terminated, otherwise it will return a failure code. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + +Notes: + pszDest should not be NULL. See StringCchGetsEx if you require the handling + of NULL values. + + cchDest must be > 1 for this function to succeed. + +Return Value: + + S_OK - data was read from stdin and copied, and the resultant + dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_END_OF_FILE / + HRESULT_CODE(hr) == ERROR_HANDLE_EOF + - this return value indicates an error or end-of-file + condition, use feof or ferror to determine which one has + occured. + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that there was + insufficient space in the destination buffer to copy any + data + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function. + +--*/ + +#ifndef STRSAFE_LIB_IMPL +STRSAFE_INLINE_API StringCchGetsA(char* pszDest, size_t cchDest); +STRSAFE_INLINE_API StringCchGetsW(wchar_t* pszDest, size_t cchDest); +#ifdef UNICODE +#define StringCchGets StringCchGetsW +#else +#define StringCchGets StringCchGetsA +#endif // !UNICODE + +STRSAFE_INLINE_API StringCchGetsA(char* pszDest, size_t cchDest) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + + hr = StringGetsExWorkerA(pszDest, cchDest, cbDest, NULL, NULL, 0); + } + + return hr; +} + +STRSAFE_INLINE_API StringCchGetsW(wchar_t* pszDest, size_t cchDest) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + hr = StringGetsExWorkerW(pszDest, cchDest, cbDest, NULL, NULL, 0); + } + + return hr; +} +#endif // !STRSAFE_NO_CCH_FUNCTIONS +#endif // !STRSAFE_LIB_IMPL + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbGets( + OUT LPTSTR pszDest, + IN size_t cbDest + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'gets'. + The size of the destination buffer (in bytes) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This routine is not a replacement for fgets. That function does not replace + newline characters with a null terminator. + + This function returns a hresult, and not a pointer. It returns + S_OK if any characters were read from stdin and copied to pszDest + and pszDest was null terminated, otherwise it will return a failure code. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + +Notes: + pszDest should not be NULL. See StringCbGetsEx if you require the handling + of NULL values. + + cbDest must be > sizeof(TCHAR) for this function to succeed. + +Return Value: + + S_OK - data was read from stdin and copied, and the resultant + dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_END_OF_FILE / + HRESULT_CODE(hr) == ERROR_HANDLE_EOF + - this return value indicates an error or end-of-file + condition, use feof or ferror to determine which one has + occured. + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that there was + insufficient space in the destination buffer to copy any + data + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function. + +--*/ + +#ifndef STRSAFE_LIB_IMPL +STRSAFE_INLINE_API StringCbGetsA(char* pszDest, size_t cbDest); +STRSAFE_INLINE_API StringCbGetsW(wchar_t* pszDest, size_t cbDest); +#ifdef UNICODE +#define StringCbGets StringCbGetsW +#else +#define StringCbGets StringCbGetsA +#endif // !UNICODE + +STRSAFE_INLINE_API StringCbGetsA(char* pszDest, size_t cbDest) +{ + HRESULT hr; + size_t cchDest; + + // convert to count of characters + cchDest = cbDest / sizeof(char); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringGetsExWorkerA(pszDest, cchDest, cbDest, NULL, NULL, 0); + } + + return hr; +} + +STRSAFE_INLINE_API StringCbGetsW(wchar_t* pszDest, size_t cbDest) +{ + HRESULT hr; + size_t cchDest; + + // convert to count of characters + cchDest = cbDest / sizeof(wchar_t); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringGetsExWorkerW(pszDest, cchDest, cbDest, NULL, NULL, 0); + } + + return hr; +} +#endif // !STRSAFE_NO_CB_FUNCTIONS +#endif // !STRSAFE_LIB_IMPL + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchGetsEx( + OUT LPTSTR pszDest OPTIONAL, + IN size_t cchDest, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcchRemaining OPTIONAL, + IN DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'gets' with + some additional parameters. In addition to functionality provided by + StringCchGets, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function copied any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return the + number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. + +Notes: + pszDest should not be NULL unless the STRSAFE_IGNORE_NULLS flag is specified. + If STRSAFE_IGNORE_NULLS is passed and pszDest is NULL, an error may still be + returned even though NULLS are ignored + + cchDest must be > 1 for this function to succeed. + +Return Value: + + S_OK - data was read from stdin and copied, and the resultant + dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_END_OF_FILE / + HRESULT_CODE(hr) == ERROR_HANDLE_EOF + - this return value indicates an error or end-of-file + condition, use feof or ferror to determine which one has + occured. + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that there was + insufficient space in the destination buffer to copy any + data + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function. + +--*/ + +#ifndef STRSAFE_LIB_IMPL +STRSAFE_INLINE_API StringCchGetsExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +STRSAFE_INLINE_API StringCchGetsExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); +#ifdef UNICODE +#define StringCchGetsEx StringCchGetsExW +#else +#define StringCchGetsEx StringCchGetsExA +#endif // !UNICODE + +STRSAFE_INLINE_API StringCchGetsExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + + hr = StringGetsExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags); + } + + return hr; +} + +STRSAFE_INLINE_API StringCchGetsExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr; + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + hr = StringGetsExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags); + } + + return hr; +} +#endif // !STRSAFE_NO_CCH_FUNCTIONS +#endif // !STRSAFE_LIB_IMPL + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbGetsEx( + OUT LPTSTR pszDest OPTIONAL, + IN size_t cbDest, + OUT LPTSTR* ppszDestEnd OPTIONAL, + OUT size_t* pcbRemaining OPTIONAL, + IN DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'gets' with + some additional parameters. In addition to functionality provided by + StringCbGets, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function copied any data, the result will point to the + null termination character + + pcbRemaining - if pbRemaining is non-null, the function will return the + number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. + +Notes: + pszDest should not be NULL unless the STRSAFE_IGNORE_NULLS flag is specified. + If STRSAFE_IGNORE_NULLS is passed and pszDest is NULL, an error may still be + returned even though NULLS are ignored + + cbDest must be > sizeof(TCHAR) for this function to succeed + +Return Value: + + S_OK - data was read from stdin and copied, and the resultant + dest string was null terminated + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + STRSAFE_E_END_OF_FILE / + HRESULT_CODE(hr) == ERROR_HANDLE_EOF + - this return value indicates an error or end-of-file + condition, use feof or ferror to determine which one has + occured. + + STRSAFE_E_INSUFFICIENT_BUFFER / + HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER + - this return value is an indication that there was + insufficient space in the destination buffer to copy any + data + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function. + +--*/ + +#ifndef STRSAFE_LIB_IMPL +STRSAFE_INLINE_API StringCbGetsExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pbRemaining, unsigned long dwFlags); +STRSAFE_INLINE_API StringCbGetsExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); +#ifdef UNICODE +#define StringCbGetsEx StringCbGetsExW +#else +#define StringCbGetsEx StringCbGetsExA +#endif // !UNICODE + +STRSAFE_INLINE_API StringCbGetsExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) +{ + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(char); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringGetsExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags); + } + + if (SUCCEEDED(hr) || + (hr == STRSAFE_E_INSUFFICIENT_BUFFER) || + (hr == STRSAFE_E_END_OF_FILE)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + } + } + + return hr; +} + +STRSAFE_INLINE_API StringCbGetsExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) +{ + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + + cchDest = cbDest / sizeof(wchar_t); + + if (cchDest > STRSAFE_MAX_CCH) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringGetsExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags); + } + + if (SUCCEEDED(hr) || + (hr == STRSAFE_E_INSUFFICIENT_BUFFER) || + (hr == STRSAFE_E_END_OF_FILE)) + { + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + + return hr; +} +#endif // !STRSAFE_NO_CB_FUNCTIONS +#endif // !STRSAFE_LIB_IMPL + +#ifndef STRSAFE_NO_CCH_FUNCTIONS +/*++ + +STDAPI +StringCchLength( + IN LPCTSTR psz, + IN size_t cchMax, + OUT size_t* pcch OPTIONAL + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strlen'. + It is used to make sure a string is not larger than a given length, and + it optionally returns the current length in characters not including + the null terminator. + + This function returns a hresult, and not a pointer. It returns + S_OK if the string is non-null and the length including the null + terminator is less than or equal to cchMax characters. + +Arguments: + + psz - string to check the length of + + cchMax - maximum number of characters including the null terminator + that psz is allowed to contain + + pcch - if the function succeeds and pcch is non-null, the current length + in characters of psz excluding the null terminator will be returned. + This out parameter is equivalent to the return value of strlen(psz) + +Notes: + psz can be null but the function will fail + + cchMax should be greater than zero or the function will fail + +Return Value: + + S_OK - psz is non-null and the length including the null + terminator is less than or equal to cchMax characters + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function. + +--*/ + +STRSAFEAPI StringCchLengthA(const char* psz, size_t cchMax, size_t* pcch); +STRSAFEAPI StringCchLengthW(const wchar_t* psz, size_t cchMax, size_t* pcch); +#ifdef UNICODE +#define StringCchLength StringCchLengthW +#else +#define StringCchLength StringCchLengthA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCchLengthA(const char* psz, size_t cchMax, size_t* pcch) +{ + HRESULT hr; + + if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringLengthWorkerA(psz, cchMax, pcch); + } + + return hr; +} + +STRSAFEAPI StringCchLengthW(const wchar_t* psz, size_t cchMax, size_t* pcch) +{ + HRESULT hr; + + if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringLengthWorkerW(psz, cchMax, pcch); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CCH_FUNCTIONS + + +#ifndef STRSAFE_NO_CB_FUNCTIONS +/*++ + +STDAPI +StringCbLength( + IN LPCTSTR psz, + IN size_t cbMax, + OUT size_t* pcb OPTIONAL + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strlen'. + It is used to make sure a string is not larger than a given length, and + it optionally returns the current length in bytes not including + the null terminator. + + This function returns a hresult, and not a pointer. It returns + S_OK if the string is non-null and the length including the null + terminator is less than or equal to cbMax bytes. + +Arguments: + + psz - string to check the length of + + cbMax - maximum number of bytes including the null terminator + that psz is allowed to contain + + pcb - if the function succeeds and pcb is non-null, the current length + in bytes of psz excluding the null terminator will be returned. + This out parameter is equivalent to the return value of strlen(psz) * sizeof(TCHAR) + +Notes: + psz can be null but the function will fail + + cbMax should be greater than or equal to sizeof(TCHAR) or the function will fail + +Return Value: + + S_OK - psz is non-null and the length including the null + terminator is less than or equal to cbMax bytes + + failure - you can use the macro HRESULT_CODE() to get a win32 + error code for all hresult failure cases + + It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the + return value of this function. + +--*/ + +STRSAFEAPI StringCbLengthA(const char* psz, size_t cchMax, size_t* pcch); +STRSAFEAPI StringCbLengthW(const wchar_t* psz, size_t cchMax, size_t* pcch); +#ifdef UNICODE +#define StringCbLength StringCbLengthW +#else +#define StringCbLength StringCbLengthA +#endif // !UNICODE + +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCbLengthA(const char* psz, size_t cbMax, size_t* pcb) +{ + HRESULT hr; + size_t cchMax; + size_t cch = 0; + + cchMax = cbMax / sizeof(char); + + if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringLengthWorkerA(psz, cchMax, &cch); + } + + if (SUCCEEDED(hr) && pcb) + { + // safe to multiply cch * sizeof(char) since cch < STRSAFE_MAX_CCH and sizeof(char) is 1 + *pcb = cch * sizeof(char); + } + + return hr; +} + +STRSAFEAPI StringCbLengthW(const wchar_t* psz, size_t cbMax, size_t* pcb) +{ + HRESULT hr; + size_t cchMax; + size_t cch = 0; + + cchMax = cbMax / sizeof(wchar_t); + + if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = StringLengthWorkerW(psz, cchMax, &cch); + } + + if (SUCCEEDED(hr) && pcb) + { + // safe to multiply cch * sizeof(wchar_t) since cch < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcb = cch * sizeof(wchar_t); + } + + return hr; +} +#endif // STRSAFE_INLINE +#endif // !STRSAFE_NO_CB_FUNCTIONS + + +// these are the worker functions that actually do the work +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCopyWorkerA(char* pszDest, size_t cchDest, const char* pszSrc) +{ + HRESULT hr = S_OK; + + if (cchDest == 0) + { + // can not null terminate a zero-byte dest buffer + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + while (cchDest && (*pszSrc != '\0')) + { + *pszDest++ = *pszSrc++; + cchDest--; + } + + if (cchDest == 0) + { + // we are going to truncate pszDest + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + + *pszDest= '\0'; + } + + return hr; +} + +STRSAFEAPI StringCopyWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc) +{ + HRESULT hr = S_OK; + + if (cchDest == 0) + { + // can not null terminate a zero-byte dest buffer + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + while (cchDest && (*pszSrc != L'\0')) + { + *pszDest++ = *pszSrc++; + cchDest--; + } + + if (cchDest == 0) + { + // we are going to truncate pszDest + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + + *pszDest= L'\0'; + } + + return hr; +} + +STRSAFEAPI StringCopyExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr = S_OK; + char* pszDestEnd = pszDest; + size_t cchRemaining = 0; + + // ASSERT(cbDest == (cchDest * sizeof(char)) || + // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); + + // only accept valid flags + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (pszDest == NULL) + { + if ((cchDest != 0) || (cbDest != 0)) + { + // NULL pszDest and non-zero cchDest/cbDest is invalid + hr = STRSAFE_E_INVALID_PARAMETER; + } + } + + if (pszSrc == NULL) + { + pszSrc = ""; + } + } + + if (SUCCEEDED(hr)) + { + if (cchDest == 0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + + // only fail if there was actually src data to copy + if (*pszSrc != '\0') + { + if (pszDest == NULL) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } + } + else + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + while (cchRemaining && (*pszSrc != '\0')) + { + *pszDestEnd++= *pszSrc++; + cchRemaining--; + } + + if (cchRemaining > 0) + { + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char))); + } + } + else + { + // we are going to truncate pszDest + pszDestEnd--; + cchRemaining++; + + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + + *pszDestEnd = '\0'; + } + } + } + + if (FAILED(hr)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = '\0'; + } + } + + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDestEnd = '\0'; + } + } + } + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + + return hr; +} + +STRSAFEAPI StringCopyExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr = S_OK; + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = 0; + + // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) || + // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + + // only accept valid flags + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (pszDest == NULL) + { + if ((cchDest != 0) || (cbDest != 0)) + { + // NULL pszDest and non-zero cchDest/cbDest is invalid + hr = STRSAFE_E_INVALID_PARAMETER; + } + } + + if (pszSrc == NULL) + { + pszSrc = L""; + } + } + + if (SUCCEEDED(hr)) + { + if (cchDest == 0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + + // only fail if there was actually src data to copy + if (*pszSrc != L'\0') + { + if (pszDest == NULL) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } + } + else + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + while (cchRemaining && (*pszSrc != L'\0')) + { + *pszDestEnd++= *pszSrc++; + cchRemaining--; + } + + if (cchRemaining > 0) + { + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + else + { + // we are going to truncate pszDest + pszDestEnd--; + cchRemaining++; + + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + + *pszDestEnd = L'\0'; + } + } + } + + if (FAILED(hr)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = L'\0'; + } + } + + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDestEnd = L'\0'; + } + } + } + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + + return hr; +} + +STRSAFEAPI StringCopyNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc) +{ + HRESULT hr = S_OK; + + if (cchDest == 0) + { + // can not null terminate a zero-byte dest buffer + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + while (cchDest && cchSrc && (*pszSrc != '\0')) + { + *pszDest++= *pszSrc++; + cchDest--; + cchSrc--; + } + + if (cchDest == 0) + { + // we are going to truncate pszDest + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + + *pszDest= '\0'; + } + + return hr; +} + +STRSAFEAPI StringCopyNWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc) +{ + HRESULT hr = S_OK; + + if (cchDest == 0) + { + // can not null terminate a zero-byte dest buffer + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + while (cchDest && cchSrc && (*pszSrc != L'\0')) + { + *pszDest++= *pszSrc++; + cchDest--; + cchSrc--; + } + + if (cchDest == 0) + { + // we are going to truncate pszDest + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + + *pszDest= L'\0'; + } + + return hr; +} + +STRSAFEAPI StringCopyNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr = S_OK; + char* pszDestEnd = pszDest; + size_t cchRemaining = 0; + + // ASSERT(cbDest == (cchDest * sizeof(char)) || + // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); + + // only accept valid flags + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (pszDest == NULL) + { + if ((cchDest != 0) || (cbDest != 0)) + { + // NULL pszDest and non-zero cchDest/cbDest is invalid + hr = STRSAFE_E_INVALID_PARAMETER; + } + } + + if (pszSrc == NULL) + { + pszSrc = ""; + } + } + + if (SUCCEEDED(hr)) + { + if (cchDest == 0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + + // only fail if there was actually src data to copy + if (*pszSrc != '\0') + { + if (pszDest == NULL) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } + } + else + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + while (cchRemaining && cchSrc && (*pszSrc != '\0')) + { + *pszDestEnd++= *pszSrc++; + cchRemaining--; + cchSrc--; + } + + if (cchRemaining > 0) + { + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char))); + } + } + else + { + // we are going to truncate pszDest + pszDestEnd--; + cchRemaining++; + + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + + *pszDestEnd = '\0'; + } + } + } + + if (FAILED(hr)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = '\0'; + } + } + + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDestEnd = '\0'; + } + } + } + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + + return hr; +} + +STRSAFEAPI StringCopyNExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, size_t cchSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr = S_OK; + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = 0; + + // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) || + // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + + // only accept valid flags + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (pszDest == NULL) + { + if ((cchDest != 0) || (cbDest != 0)) + { + // NULL pszDest and non-zero cchDest/cbDest is invalid + hr = STRSAFE_E_INVALID_PARAMETER; + } + } + + if (pszSrc == NULL) + { + pszSrc = L""; + } + } + + if (SUCCEEDED(hr)) + { + if (cchDest == 0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + + // only fail if there was actually src data to copy + if (*pszSrc != L'\0') + { + if (pszDest == NULL) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } + } + else + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + while (cchRemaining && cchSrc && (*pszSrc != L'\0')) + { + *pszDestEnd++= *pszSrc++; + cchRemaining--; + cchSrc--; + } + + if (cchRemaining > 0) + { + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + else + { + // we are going to truncate pszDest + pszDestEnd--; + cchRemaining++; + + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + + *pszDestEnd = L'\0'; + } + } + } + + if (FAILED(hr)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = L'\0'; + } + } + + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDestEnd = L'\0'; + } + } + } + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + + return hr; +} + +STRSAFEAPI StringCatWorkerA(char* pszDest, size_t cchDest, const char* pszSrc) +{ + HRESULT hr; + size_t cchDestCurrent; + + hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); + + if (SUCCEEDED(hr)) + { + hr = StringCopyWorkerA(pszDest + cchDestCurrent, + cchDest - cchDestCurrent, + pszSrc); + } + + return hr; +} + +STRSAFEAPI StringCatWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc) +{ + HRESULT hr; + size_t cchDestCurrent; + + hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); + + if (SUCCEEDED(hr)) + { + hr = StringCopyWorkerW(pszDest + cchDestCurrent, + cchDest - cchDestCurrent, + pszSrc); + } + + return hr; +} + +STRSAFEAPI StringCatExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr = S_OK; + char* pszDestEnd = pszDest; + size_t cchRemaining = 0; + + // ASSERT(cbDest == (cchDest * sizeof(char)) || + // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); + + // only accept valid flags + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cchDestCurrent; + + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (pszDest == NULL) + { + if ((cchDest == 0) && (cbDest == 0)) + { + cchDestCurrent = 0; + } + else + { + // NULL pszDest and non-zero cchDest/cbDest is invalid + hr = STRSAFE_E_INVALID_PARAMETER; + } + } + else + { + hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); + + if (SUCCEEDED(hr)) + { + pszDestEnd = pszDest + cchDestCurrent; + cchRemaining = cchDest - cchDestCurrent; + } + } + + if (pszSrc == NULL) + { + pszSrc = ""; + } + } + else + { + hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); + + if (SUCCEEDED(hr)) + { + pszDestEnd = pszDest + cchDestCurrent; + cchRemaining = cchDest - cchDestCurrent; + } + } + + if (SUCCEEDED(hr)) + { + if (cchDest == 0) + { + // only fail if there was actually src data to append + if (*pszSrc != '\0') + { + if (pszDest == NULL) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } + } + else + { + // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass + // those flags through + hr = StringCopyExWorkerA(pszDestEnd, + cchRemaining, + (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)), + pszSrc, + &pszDestEnd, + &cchRemaining, + dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + } + + if (FAILED(hr)) + { + if (pszDest) + { + // STRSAFE_NO_TRUNCATION is taken care of by StringCopyExWorkerA() + + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = '\0'; + } + } + + if (dwFlags & STRSAFE_NULL_ON_FAILURE) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDestEnd = '\0'; + } + } + } + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + + return hr; +} + +STRSAFEAPI StringCatExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr = S_OK; + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = 0; + + // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) || + // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + + // only accept valid flags + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + size_t cchDestCurrent; + + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (pszDest == NULL) + { + if ((cchDest == 0) && (cbDest == 0)) + { + cchDestCurrent = 0; + } + else + { + // NULL pszDest and non-zero cchDest/cbDest is invalid + hr = STRSAFE_E_INVALID_PARAMETER; + } + } + else + { + hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); + + if (SUCCEEDED(hr)) + { + pszDestEnd = pszDest + cchDestCurrent; + cchRemaining = cchDest - cchDestCurrent; + } + } + + if (pszSrc == NULL) + { + pszSrc = L""; + } + } + else + { + hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); + + if (SUCCEEDED(hr)) + { + pszDestEnd = pszDest + cchDestCurrent; + cchRemaining = cchDest - cchDestCurrent; + } + } + + if (SUCCEEDED(hr)) + { + if (cchDest == 0) + { + // only fail if there was actually src data to append + if (*pszSrc != L'\0') + { + if (pszDest == NULL) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } + } + else + { + // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass + // those flags through + hr = StringCopyExWorkerW(pszDestEnd, + cchRemaining, + (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)), + pszSrc, + &pszDestEnd, + &cchRemaining, + dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + } + + if (FAILED(hr)) + { + if (pszDest) + { + // STRSAFE_NO_TRUNCATION is taken care of by StringCopyExWorkerW() + + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = L'\0'; + } + } + + if (dwFlags & STRSAFE_NULL_ON_FAILURE) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDestEnd = L'\0'; + } + } + } + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + + return hr; +} + +STRSAFEAPI StringCatNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend) +{ + HRESULT hr; + size_t cchDestCurrent; + + hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); + + if (SUCCEEDED(hr)) + { + hr = StringCopyNWorkerA(pszDest + cchDestCurrent, + cchDest - cchDestCurrent, + pszSrc, + cchMaxAppend); + } + + return hr; +} + +STRSAFEAPI StringCatNWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend) +{ + HRESULT hr; + size_t cchDestCurrent; + + hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); + + if (SUCCEEDED(hr)) + { + hr = StringCopyNWorkerW(pszDest + cchDestCurrent, + cchDest - cchDestCurrent, + pszSrc, + cchMaxAppend); + } + + return hr; +} + +STRSAFEAPI StringCatNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr = S_OK; + char* pszDestEnd = pszDest; + size_t cchRemaining = 0; + size_t cchDestCurrent = 0; + + // ASSERT(cbDest == (cchDest * sizeof(char)) || + // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); + + // only accept valid flags + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (pszDest == NULL) + { + if ((cchDest == 0) && (cbDest == 0)) + { + cchDestCurrent = 0; + } + else + { + // NULL pszDest and non-zero cchDest/cbDest is invalid + hr = STRSAFE_E_INVALID_PARAMETER; + } + } + else + { + hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); + + if (SUCCEEDED(hr)) + { + pszDestEnd = pszDest + cchDestCurrent; + cchRemaining = cchDest - cchDestCurrent; + } + } + + if (pszSrc == NULL) + { + pszSrc = ""; + } + } + else + { + hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); + + if (SUCCEEDED(hr)) + { + pszDestEnd = pszDest + cchDestCurrent; + cchRemaining = cchDest - cchDestCurrent; + } + } + + if (SUCCEEDED(hr)) + { + if (cchDest == 0) + { + // only fail if there was actually src data to append + if (*pszSrc != '\0') + { + if (pszDest == NULL) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } + } + else + { + // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass + // those flags through + hr = StringCopyNExWorkerA(pszDestEnd, + cchRemaining, + (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)), + pszSrc, + cchMaxAppend, + &pszDestEnd, + &cchRemaining, + dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + } + + if (FAILED(hr)) + { + if (pszDest) + { + // STRSAFE_NO_TRUNCATION is taken care of by StringCopyNExWorkerA() + + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = '\0'; + } + } + + if (dwFlags & (STRSAFE_NULL_ON_FAILURE)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDestEnd = '\0'; + } + } + } + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + + return hr; +} + +STRSAFEAPI StringCatNExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, size_t cchMaxAppend, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr = S_OK; + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = 0; + size_t cchDestCurrent = 0; + + + // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) || + // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + + // only accept valid flags + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (pszDest == NULL) + { + if ((cchDest == 0) && (cbDest == 0)) + { + cchDestCurrent = 0; + } + else + { + // NULL pszDest and non-zero cchDest/cbDest is invalid + hr = STRSAFE_E_INVALID_PARAMETER; + } + } + else + { + hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); + + if (SUCCEEDED(hr)) + { + pszDestEnd = pszDest + cchDestCurrent; + cchRemaining = cchDest - cchDestCurrent; + } + } + + if (pszSrc == NULL) + { + pszSrc = L""; + } + } + else + { + hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); + + if (SUCCEEDED(hr)) + { + pszDestEnd = pszDest + cchDestCurrent; + cchRemaining = cchDest - cchDestCurrent; + } + } + + if (SUCCEEDED(hr)) + { + if (cchDest == 0) + { + // only fail if there was actually src data to append + if (*pszSrc != L'\0') + { + if (pszDest == NULL) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } + } + else + { + // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass + // those flags through + hr = StringCopyNExWorkerW(pszDestEnd, + cchRemaining, + (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)), + pszSrc, + cchMaxAppend, + &pszDestEnd, + &cchRemaining, + dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + } + + if (FAILED(hr)) + { + if (pszDest) + { + // STRSAFE_NO_TRUNCATION is taken care of by StringCopyNExWorkerW() + + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = L'\0'; + } + } + + if (dwFlags & (STRSAFE_NULL_ON_FAILURE)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDestEnd = L'\0'; + } + } + } + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + + return hr; +} + +STRSAFEAPI StringVPrintfWorkerA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList) +{ + HRESULT hr = S_OK; + + if (cchDest == 0) + { + // can not null terminate a zero-byte dest buffer + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + int iRet; + size_t cchMax; + + // leave the last space for the null terminator + cchMax = cchDest - 1; + + iRet = _vsnprintf(pszDest, cchMax, pszFormat, argList); + // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax)); + + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + // need to null terminate the string + pszDest += cchMax; + *pszDest = '\0'; + + // we have truncated pszDest + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + else if (((size_t)iRet) == cchMax) + { + // need to null terminate the string + pszDest += cchMax; + *pszDest = '\0'; + } + } + + return hr; +} + +STRSAFEAPI StringVPrintfWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, va_list argList) +{ + HRESULT hr = S_OK; + + if (cchDest == 0) + { + // can not null terminate a zero-byte dest buffer + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + int iRet; + size_t cchMax; + + // leave the last space for the null terminator + cchMax = cchDest - 1; + + iRet = _vsnwprintf(pszDest, cchMax, pszFormat, argList); + // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax)); + + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + // need to null terminate the string + pszDest += cchMax; + *pszDest = L'\0'; + + // we have truncated pszDest + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + else if (((size_t)iRet) == cchMax) + { + // need to null terminate the string + pszDest += cchMax; + *pszDest = L'\0'; + } + } + + return hr; +} + +STRSAFEAPI StringVPrintfExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList) +{ + HRESULT hr = S_OK; + char* pszDestEnd = pszDest; + size_t cchRemaining = 0; + + // ASSERT(cbDest == (cchDest * sizeof(char)) || + // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); + + // only accept valid flags + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (pszDest == NULL) + { + if ((cchDest != 0) || (cbDest != 0)) + { + // NULL pszDest and non-zero cchDest/cbDest is invalid + hr = STRSAFE_E_INVALID_PARAMETER; + } + } + + if (pszFormat == NULL) + { + pszFormat = ""; + } + } + + if (SUCCEEDED(hr)) + { + if (cchDest == 0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + + // only fail if there was actually a non-empty format string + if (*pszFormat != '\0') + { + if (pszDest == NULL) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } + } + else + { + int iRet; + size_t cchMax; + + // leave the last space for the null terminator + cchMax = cchDest - 1; + + iRet = _vsnprintf(pszDest, cchMax, pszFormat, argList); + // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax)); + + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + // we have truncated pszDest + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + + // need to null terminate the string + *pszDestEnd = '\0'; + + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + else if (((size_t)iRet) == cchMax) + { + // string fit perfectly + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + + // need to null terminate the string + *pszDestEnd = '\0'; + } + else if (((size_t)iRet) < cchMax) + { + // there is extra room + pszDestEnd = pszDest + iRet; + cchRemaining = cchDest - iRet; + + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char))); + } + } + } + } + } + + if (FAILED(hr)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = '\0'; + } + } + + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDestEnd = '\0'; + } + } + } + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + + return hr; +} + +STRSAFEAPI StringVPrintfExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList) +{ + HRESULT hr = S_OK; + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = 0; + + // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) || + // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + + // only accept valid flags + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (pszDest == NULL) + { + if ((cchDest != 0) || (cbDest != 0)) + { + // NULL pszDest and non-zero cchDest/cbDest is invalid + hr = STRSAFE_E_INVALID_PARAMETER; + } + } + + if (pszFormat == NULL) + { + pszFormat = L""; + } + } + + if (SUCCEEDED(hr)) + { + if (cchDest == 0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + + // only fail if there was actually a non-empty format string + if (*pszFormat != L'\0') + { + if (pszDest == NULL) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } + } + else + { + int iRet; + size_t cchMax; + + // leave the last space for the null terminator + cchMax = cchDest - 1; + + iRet = _vsnwprintf(pszDest, cchMax, pszFormat, argList); + // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax)); + + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + // we have truncated pszDest + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + + // need to null terminate the string + *pszDestEnd = L'\0'; + + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + else if (((size_t)iRet) == cchMax) + { + // string fit perfectly + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + + // need to null terminate the string + *pszDestEnd = L'\0'; + } + else if (((size_t)iRet) < cchMax) + { + // there is extra room + pszDestEnd = pszDest + iRet; + cchRemaining = cchDest - iRet; + + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + } + } + } + + if (FAILED(hr)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = L'\0'; + } + } + + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDestEnd = L'\0'; + } + } + } + } + + if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + + return hr; +} + +STRSAFEAPI StringLengthWorkerA(const char* psz, size_t cchMax, size_t* pcch) +{ + HRESULT hr = S_OK; + size_t cchMaxPrev = cchMax; + + while (cchMax && (*psz != '\0')) + { + psz++; + cchMax--; + } + + if (cchMax == 0) + { + // the string is longer than cchMax + hr = STRSAFE_E_INVALID_PARAMETER; + } + + if (SUCCEEDED(hr) && pcch) + { + *pcch = cchMaxPrev - cchMax; + } + + return hr; +} + +STRSAFEAPI StringLengthWorkerW(const wchar_t* psz, size_t cchMax, size_t* pcch) +{ + HRESULT hr = S_OK; + size_t cchMaxPrev = cchMax; + + while (cchMax && (*psz != L'\0')) + { + psz++; + cchMax--; + } + + if (cchMax == 0) + { + // the string is longer than cchMax + hr = STRSAFE_E_INVALID_PARAMETER; + } + + if (SUCCEEDED(hr) && pcch) + { + *pcch = cchMaxPrev - cchMax; + } + + return hr; +} +#endif // STRSAFE_INLINE + +#ifndef STRSAFE_LIB_IMPL +STRSAFE_INLINE_API StringGetsExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr = S_OK; + char* pszDestEnd = pszDest; + size_t cchRemaining = 0; + + // ASSERT(cbDest == (cchDest * sizeof(char)) || + // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); + + // only accept valid flags + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (pszDest == NULL) + { + if ((cchDest != 0) || (cbDest != 0)) + { + // NULL pszDest and non-zero cchDest/cbDest is invalid + hr = STRSAFE_E_INVALID_PARAMETER; + } + } + } + + if (SUCCEEDED(hr)) + { + if (cchDest <= 1) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + if (cchDest == 1) + { + *pszDestEnd = '\0'; + } + + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + else + { + char ch; + + pszDestEnd = pszDest; + cchRemaining = cchDest; + + while ((cchRemaining > 1) && (ch = (char)getc(stdin)) != '\n') + { + if (ch == EOF) + { + if (pszDestEnd == pszDest) + { + // we failed to read anything from stdin + hr = STRSAFE_E_END_OF_FILE; + } + break; + } + + *pszDestEnd = ch; + + pszDestEnd++; + cchRemaining--; + } + + if (cchRemaining > 0) + { + // there is extra room + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char))); + } + } + + *pszDestEnd = '\0'; + } + } + } + + if (FAILED(hr)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = '\0'; + } + } + + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDestEnd = '\0'; + } + } + } + } + + if (SUCCEEDED(hr) || + (hr == STRSAFE_E_INSUFFICIENT_BUFFER) || + (hr == STRSAFE_E_END_OF_FILE)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + + return hr; +} + +STRSAFE_INLINE_API StringGetsExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +{ + HRESULT hr = S_OK; + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = 0; + + // ASSERT(cbDest == (cchDest * sizeof(char)) || + // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); + + // only accept valid flags + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (pszDest == NULL) + { + if ((cchDest != 0) || (cbDest != 0)) + { + // NULL pszDest and non-zero cchDest/cbDest is invalid + hr = STRSAFE_E_INVALID_PARAMETER; + } + } + } + + if (SUCCEEDED(hr)) + { + if (cchDest <= 1) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + if (cchDest == 1) + { + *pszDestEnd = L'\0'; + } + + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + else + { + wchar_t ch; + + pszDestEnd = pszDest; + cchRemaining = cchDest; + + while ((cchRemaining > 1) && (ch = (wchar_t)getwc(stdin)) != L'\n') + { + if (ch == EOF) + { + if (pszDestEnd == pszDest) + { + // we failed to read anything from stdin + hr = STRSAFE_E_END_OF_FILE; + } + break; + } + + *pszDestEnd = ch; + + pszDestEnd++; + cchRemaining--; + } + + if (cchRemaining > 0) + { + // there is extra room + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + + *pszDestEnd = L'\0'; + } + } + } + + if (FAILED(hr)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = L'\0'; + } + } + + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDestEnd = L'\0'; + } + } + } + } + + if (SUCCEEDED(hr) || + (hr == STRSAFE_E_INSUFFICIENT_BUFFER) || + (hr == STRSAFE_E_END_OF_FILE)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + + return hr; +} +#endif // !STRSAFE_LIB_IMPL + + +// Do not call these functions, they are worker functions for internal use within this file +#ifdef DEPRECATE_SUPPORTED +#pragma deprecated(StringCopyWorkerA) +#pragma deprecated(StringCopyWorkerW) +#pragma deprecated(StringCopyExWorkerA) +#pragma deprecated(StringCopyExWorkerW) +#pragma deprecated(StringCatWorkerA) +#pragma deprecated(StringCatWorkerW) +#pragma deprecated(StringCatExWorkerA) +#pragma deprecated(StringCatExWorkerW) +#pragma deprecated(StringCatNWorkerA) +#pragma deprecated(StringCatNWorkerW) +#pragma deprecated(StringCatNExWorkerA) +#pragma deprecated(StringCatNExWorkerW) +#pragma deprecated(StringVPrintfWorkerA) +#pragma deprecated(StringVPrintfWorkerW) +#pragma deprecated(StringVPrintfExWorkerA) +#pragma deprecated(StringVPrintfExWorkerW) +#pragma deprecated(StringLengthWorkerA) +#pragma deprecated(StringLengthWorkerW) +#else +#define StringCopyWorkerA StringCopyWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA; +#define StringCopyWorkerW StringCopyWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW; +#define StringCopyExWorkerA StringCopyExWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA; +#define StringCopyExWorkerW StringCopyExWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW; +#define StringCatWorkerA StringCatWorkerA_instead_use_StringCchCatA_or_StringCchCatExA; +#define StringCatWorkerW StringCatWorkerW_instead_use_StringCchCatW_or_StringCchCatExW; +#define StringCatExWorkerA StringCatExWorkerA_instead_use_StringCchCatA_or_StringCchCatExA; +#define StringCatExWorkerW StringCatExWorkerW_instead_use_StringCchCatW_or_StringCchCatExW; +#define StringCatNWorkerA StringCatNWorkerA_instead_use_StringCchCatNA_or_StrincCbCatNA; +#define StringCatNWorkerW StringCatNWorkerW_instead_use_StringCchCatNW_or_StringCbCatNW; +#define StringCatNExWorkerA StringCatNExWorkerA_instead_use_StringCchCatNExA_or_StringCbCatNExA; +#define StringCatNExWorkerW StringCatNExWorkerW_instead_use_StringCchCatNExW_or_StringCbCatNExW; +#define StringVPrintfWorkerA StringVPrintfWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA; +#define StringVPrintfWorkerW StringVPrintfWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW; +#define StringVPrintfExWorkerA StringVPrintfExWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA; +#define StringVPrintfExWorkerW StringVPrintfExWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW; +#define StringLengthWorkerA StringLengthWorkerA_instead_use_StringCchLengthA_or_StringCbLengthA; +#define StringLengthWorkerW StringLengthWorkerW_instead_use_StringCchLengthW_or_StringCbLengthW; +#endif // !DEPRECATE_SUPPORTED + + +#ifndef STRSAFE_NO_DEPRECATE +// Deprecate all of the unsafe functions to generate compiletime errors. If you do not want +// this then you can #define STRSAFE_NO_DEPRECATE before including this file. +#ifdef DEPRECATE_SUPPORTED + +// First all the names that are a/w variants (or shouldn't be #defined by now anyway). +#pragma deprecated(lstrcpyA) +#pragma deprecated(lstrcpyW) +#pragma deprecated(lstrcatA) +#pragma deprecated(lstrcatW) +#pragma deprecated(wsprintfA) +#pragma deprecated(wsprintfW) + +#pragma deprecated(StrCpyW) +#pragma deprecated(StrCatW) +#pragma deprecated(StrNCatA) +#pragma deprecated(StrNCatW) +#pragma deprecated(StrCatNA) +#pragma deprecated(StrCatNW) +#pragma deprecated(wvsprintfA) +#pragma deprecated(wvsprintfW) + +#pragma deprecated(strcpy) +#pragma deprecated(wcscpy) +#pragma deprecated(strcat) +#pragma deprecated(wcscat) +#pragma deprecated(sprintf) +#pragma deprecated(swprintf) +#pragma deprecated(vsprintf) +#pragma deprecated(vswprintf) +#pragma deprecated(_snprintf) +#pragma deprecated(_snwprintf) +#pragma deprecated(_vsnprintf) +#pragma deprecated(_vsnwprintf) +#pragma deprecated(gets) +#pragma deprecated(_getws) + +// Then all the windows.h names - we need to undef and redef based on UNICODE setting +#undef lstrcpy +#undef lstrcat +#undef wsprintf +#undef wvsprintf +#pragma deprecated(lstrcpy) +#pragma deprecated(lstrcat) +#pragma deprecated(wsprintf) +#pragma deprecated(wvsprintf) +#ifdef UNICODE +#define lstrcpy lstrcpyW +#define lstrcat lstrcatW +#define wsprintf wsprintfW +#define wvsprintf wvsprintfW +#else +#define lstrcpy lstrcpyA +#define lstrcat lstrcatA +#define wsprintf wsprintfA +#define wvsprintf wvsprintfA +#endif + +// Then the shlwapi names - they key off UNICODE also. +#undef StrCpyA +#undef StrCpy +#undef StrCatA +#undef StrCat +#undef StrNCat +#undef StrCatN +#pragma deprecated(StrCpyA) +#pragma deprecated(StrCatA) +#pragma deprecated(StrCatN) +#pragma deprecated(StrCpy) +#pragma deprecated(StrCat) +#pragma deprecated(StrNCat) +#define StrCpyA lstrcpyA +#define StrCatA lstrcatA +#define StrCatN StrNCat +#ifdef UNICODE +#define StrCpy StrCpyW +#define StrCat StrCatW +#define StrNCat StrNCatW +#else +#define StrCpy lstrcpyA +#define StrCat lstrcatA +#define StrNCat StrNCatA +#endif + +// Then all the CRT names - we need to undef/redef based on _UNICODE value. +#undef _tcscpy +#undef _ftcscpy +#undef _tcscat +#undef _ftcscat +#undef _stprintf +#undef _sntprintf +#undef _vstprintf +#undef _vsntprintf +#undef _getts +#pragma deprecated(_tcscpy) +#pragma deprecated(_ftcscpy) +#pragma deprecated(_tcscat) +#pragma deprecated(_ftcscat) +#pragma deprecated(_stprintf) +#pragma deprecated(_sntprintf) +#pragma deprecated(_vstprintf) +#pragma deprecated(_vsntprintf) +#pragma deprecated(_getts) +#ifdef _UNICODE +#define _tcscpy wcscpy +#define _ftcscpy wcscpy +#define _tcscat wcscat +#define _ftcscat wcscat +#define _stprintf swprintf +#define _sntprintf _snwprintf +#define _vstprintf vswprintf +#define _vsntprintf _vsnwprintf +#define _getts _getws +#else +#define _tcscpy strcpy +#define _ftcscpy strcpy +#define _tcscat strcat +#define _ftcscat strcat +#define _stprintf sprintf +#define _sntprintf _snprintf +#define _vstprintf vsprintf +#define _vsntprintf _vsnprintf +#define _getts gets +#endif + +#else // DEPRECATE_SUPPORTED + +#undef strcpy +#define strcpy strcpy_instead_use_StringCbCopyA_or_StringCchCopyA; + +#undef wcscpy +#define wcscpy wcscpy_instead_use_StringCbCopyW_or_StringCchCopyW; + +#undef strcat +#define strcat strcat_instead_use_StringCbCatA_or_StringCchCatA; + +#undef wcscat +#define wcscat wcscat_instead_use_StringCbCatW_or_StringCchCatW; + +#undef sprintf +#define sprintf sprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA; + +#undef swprintf +#define swprintf swprintf_instead_use_StringCbPrintfW_or_StringCchPrintfW; + +#undef vsprintf +#define vsprintf vsprintf_instead_use_StringCbVPrintfA_or_StringCchVPrintfA; + +#undef vswprintf +#define vswprintf vswprintf_instead_use_StringCbVPrintfW_or_StringCchVPrintfW; + +#undef _snprintf +#define _snprintf _snprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA; + +#undef _snwprintf +#define _snwprintf _snwprintf_instead_use_StringCbPrintfW_or_StringCchPrintfW; + +#undef _vsnprintf +#define _vsnprintf _vsnprintf_instead_use_StringCbVPrintfA_or_StringCchVPrintfA; + +#undef _vsnwprintf +#define _vsnwprintf _vsnwprintf_instead_use_StringCbVPrintfW_or_StringCchVPrintfW; + +#undef strcpyA +#define strcpyA strcpyA_instead_use_StringCbCopyA_or_StringCchCopyA; + +#undef strcpyW +#define strcpyW strcpyW_instead_use_StringCbCopyW_or_StringCchCopyW; + +#undef lstrcpy +#define lstrcpy lstrcpy_instead_use_StringCbCopy_or_StringCchCopy; + +#undef lstrcpyA +#define lstrcpyA lstrcpyA_instead_use_StringCbCopyA_or_StringCchCopyA; + +#undef lstrcpyW +#define lstrcpyW lstrcpyW_instead_use_StringCbCopyW_or_StringCchCopyW; + +#undef StrCpy +#define StrCpy StrCpy_instead_use_StringCbCopy_or_StringCchCopy; + +#undef StrCpyA +#define StrCpyA StrCpyA_instead_use_StringCbCopyA_or_StringCchCopyA; + +#undef StrCpyW +#define StrCpyW StrCpyW_instead_use_StringCbCopyW_or_StringCchCopyW; + +#undef _tcscpy +#define _tcscpy _tcscpy_instead_use_StringCbCopy_or_StringCchCopy; + +#undef _ftcscpy +#define _ftcscpy _ftcscpy_instead_use_StringCbCopy_or_StringCchCopy; + +#undef lstrcat +#define lstrcat lstrcat_instead_use_StringCbCat_or_StringCchCat; + +#undef lstrcatA +#define lstrcatA lstrcatA_instead_use_StringCbCatA_or_StringCchCatA; + +#undef lstrcatW +#define lstrcatW lstrcatW_instead_use_StringCbCatW_or_StringCchCatW; + +#undef StrCat +#define StrCat StrCat_instead_use_StringCbCat_or_StringCchCat; + +#undef StrCatA +#define StrCatA StrCatA_instead_use_StringCbCatA_or_StringCchCatA; + +#undef StrCatW +#define StrCatW StrCatW_instead_use_StringCbCatW_or_StringCchCatW; + +#undef StrNCat +#define StrNCat StrNCat_instead_use_StringCbCatN_or_StringCchCatN; + +#undef StrNCatA +#define StrNCatA StrNCatA_instead_use_StringCbCatNA_or_StringCchCatNA; + +#undef StrNCatW +#define StrNCatW StrNCatW_instead_use_StringCbCatNW_or_StringCchCatNW; + +#undef StrCatN +#define StrCatN StrCatN_instead_use_StringCbCatN_or_StringCchCatN; + +#undef StrCatNA +#define StrCatNA StrCatNA_instead_use_StringCbCatNA_or_StringCchCatNA; + +#undef StrCatNW +#define StrCatNW StrCatNW_instead_use_StringCbCatNW_or_StringCchCatNW; + +#undef _tcscat +#define _tcscat _tcscat_instead_use_StringCbCat_or_StringCchCat; + +#undef _ftcscat +#define _ftcscat _ftcscat_instead_use_StringCbCat_or_StringCchCat; + +#undef wsprintf +#define wsprintf wsprintf_instead_use_StringCbPrintf_or_StringCchPrintf; + +#undef wsprintfA +#define wsprintfA wsprintfA_instead_use_StringCbPrintfA_or_StringCchPrintfA; + +#undef wsprintfW +#define wsprintfW wsprintfW_instead_use_StringCbPrintfW_or_StringCchPrintfW; + +#undef wvsprintf +#define wvsprintf wvsprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf; + +#undef wvsprintfA +#define wvsprintfA wvsprintfA_instead_use_StringCbVPrintfA_or_StringCchVPrintfA; + +#undef wvsprintfW +#define wvsprintfW wvsprintfW_instead_use_StringCbVPrintfW_or_StringCchVPrintfW; + +#undef _vstprintf +#define _vstprintf _vstprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf; + +#undef _vsntprintf +#define _vsntprintf _vsntprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf; + +#undef _stprintf +#define _stprintf _stprintf_instead_use_StringCbPrintf_or_StringCchPrintf; + +#undef _sntprintf +#define _sntprintf _sntprintf_instead_use_StringCbPrintf_or_StringCchPrintf; + +#undef _getts +#define _getts _getts_instead_use_StringCbGets_or_StringCchGets; + +#undef gets +#define gets _gets_instead_use_StringCbGetsA_or_StringCchGetsA; + +#undef _getws +#define _getws _getws_instead_use_StringCbGetsW_or_StringCchGetsW; + +#endif // !DEPRECATE_SUPPORTED +#endif // !STRSAFE_NO_DEPRECATE + +#ifdef _NTSTRSAFE_H_INCLUDED_ +#pragma warning(pop) +#endif // _NTSTRSAFE_H_INCLUDED_ + +#endif // _STRSAFE_H_INCLUDED_ diff --git a/cpp/pipe/src/pipe.c b/cpp/pipe/src/pipe.c new file mode 100644 index 0000000..1a35caa --- /dev/null +++ b/cpp/pipe/src/pipe.c @@ -0,0 +1,192 @@ +#include +#include +#include +#include "pipe.h" + +#define DEBUG 0 + +JNIEXPORT jint JNICALL Java_pipe_Pipe_CreateNamedPipe(JNIEnv *env, + jclass className, jstring sPipeName, jint dwOpenMode, jint dwPipeMode, + jint nMaxInstances, jint nOutBufferSize, jint nInBufferSize, + jint nDefaultTimeOut, jint lpSecurityAttributes) { + HANDLE pipeHandler; + LPCSTR pipeName; + pipeName = (*env)->GetStringUTFChars(env, sPipeName, NULL ); + if (pipeName == NULL ) + return -1; + + if (DEBUG) { + printf("Native: Pipe Name %s\n", pipeName); + printf("Native: dwOpenMode %d\n", dwOpenMode); + printf("Native: dwPipeMode %d\n", dwPipeMode); + printf("Native: nMaxInstances %d\n", nMaxInstances); + printf("Native: nOutBufferSize %d\n", nOutBufferSize); + printf("Native: nInBufferSize %d\n", nInBufferSize); + printf("Native: nDefaultTimeOut %d\n", nDefaultTimeOut); + } + + pipeHandler = CreateNamedPipe((LPCSTR) pipeName, dwOpenMode, dwPipeMode, + nMaxInstances, nOutBufferSize, nInBufferSize, nDefaultTimeOut, + (LPSECURITY_ATTRIBUTES) lpSecurityAttributes); + + (*env)->ReleaseStringUTFChars(env, sPipeName, pipeName); + return (jint) pipeHandler; +} + +JNIEXPORT jboolean JNICALL Java_pipe_Pipe_ConnectNamedPipe(JNIEnv *env, + jclass className, jint hNamedPipe, jint lpOverlapped) { + BOOL fConnected; + HANDLE pipeHandler = (HANDLE) hNamedPipe; + fConnected = ConnectNamedPipe(pipeHandler, (LPOVERLAPPED) lpOverlapped); + return fConnected; +} + +JNIEXPORT jint JNICALL Java_pipe_Pipe_GetLastError(JNIEnv *env, + jclass className) { + DWORD errorNumber = GetLastError(); + return (jint) errorNumber; +} + +JNIEXPORT jboolean JNICALL Java_pipe_Pipe_CloseHandle(JNIEnv *env, + jclass className, jint hNamedPipe) { + BOOL result; + HANDLE pipeHandler = (HANDLE) hNamedPipe; + result = CloseHandle(pipeHandler); + return result; +} + +JNIEXPORT jbyteArray JNICALL Java_pipe_Pipe_ReadFile(JNIEnv *env, + jclass className, jint hNamedPipe, jint nNumberOfBytesToRead) { + int bytesRead = 0; + BOOL result; + HANDLE pipeHandler = (HANDLE) hNamedPipe; + LPVOID buffer; + jbyteArray lpBuffer; + + buffer = (LPVOID) LocalAlloc(LMEM_ZEROINIT, nNumberOfBytesToRead); + + if (DEBUG) { + printf( + "Native: Before ReadFile pipeHandler %d nNumberOfBytesToRead %d\n", + pipeHandler, nNumberOfBytesToRead); + } + result = ReadFile(pipeHandler, (LPVOID) buffer, + (DWORD) nNumberOfBytesToRead, &bytesRead, (LPOVERLAPPED) 0); + if (result) { + lpBuffer = (*env)->NewByteArray(env, (jsize) bytesRead); + (*env)->SetByteArrayRegion(env, lpBuffer, 0, (jsize) bytesRead, + (jbyte *) buffer); + } else + bytesRead = 0; + + LocalFree(buffer); + + if (DEBUG) { + printf("Native: After ReadFile BytesRead %d\n", bytesRead); + } + return lpBuffer; +} + +JNIEXPORT jint JNICALL Java_pipe_Pipe_WriteFile(JNIEnv *env, jclass className, + jint hNamedPipe, jbyteArray lpBuffer, jint nNumberOfBytesToWrite) { + int bytesWritten = 0; + BOOL result; + HANDLE pipeHandler = (HANDLE) hNamedPipe; + LPVOID buffer; + + buffer = (LPVOID) LocalAlloc(LMEM_ZEROINIT, nNumberOfBytesToWrite); + + (*env)->GetByteArrayRegion(env, lpBuffer, 0, nNumberOfBytesToWrite, buffer); + result = WriteFile(pipeHandler, buffer, (DWORD) nNumberOfBytesToWrite, + (LPDWORD) &bytesWritten, (LPOVERLAPPED) 0); + LocalFree(buffer); + + if (DEBUG) { + printf("Native: After WriteFile BytesReadWritten %d\n", bytesWritten); + } + + if (!result) { + if (GetLastError() != ERROR_IO_PENDING) + result = 0; + else + result = 1; + } + if (!result) { + bytesWritten = -1; + } + return bytesWritten; +} + +JNIEXPORT jboolean JNICALL Java_pipe_Pipe_FlushFileBuffers(JNIEnv *env, + jclass className, jint hNamedPipe) { + BOOL result; + HANDLE pipeHandler = (HANDLE) hNamedPipe; + result = FlushFileBuffers(pipeHandler); + return result; +} + +JNIEXPORT jboolean JNICALL Java_pipe_Pipe_DisconnectNamedPipe(JNIEnv *env, + jclass className, jint hNamedPipe) { + BOOL result; + HANDLE pipeHandler = (HANDLE) hNamedPipe; + result = DisconnectNamedPipe(pipeHandler); + return result; +} + +JNIEXPORT jint JNICALL Java_pipe_Pipe_CreateFile(JNIEnv *env, jclass className, + jstring lpFileName, jint dwDesiredAccess, jint dwShareMode, + jint lpSecurityAttributes, jint dwCreationDisposition, + jint dwFlagsAndAttributes, jint hTemplateFile) { + HANDLE pipeHandler; + const jbyte *fileName; + fileName = (*env)->GetStringUTFChars(env, lpFileName, NULL ); + if (fileName == NULL ) + return -1; + pipeHandler = CreateFile((LPCSTR) fileName, (DWORD) dwDesiredAccess, + (DWORD) dwShareMode, (LPSECURITY_ATTRIBUTES) lpSecurityAttributes, + (DWORD) dwCreationDisposition, (DWORD) dwFlagsAndAttributes, + (HANDLE) hTemplateFile); + return (jint) pipeHandler; +} + +JNIEXPORT jboolean JNICALL Java_pipe_Pipe_WaitNamedPipe(JNIEnv *env, + jclass className, jstring lpNamedPipeName, jint nTimeOut) { + BOOL result; + const jbyte *pipeName; + pipeName = (*env)->GetStringUTFChars(env, lpNamedPipeName, NULL ); + if (pipeName == NULL ) + return 0; + result = WaitNamedPipe((LPCSTR) pipeName, (DWORD) nTimeOut); + return result; +} + +JNIEXPORT jstring JNICALL Java_pipe_Pipe_FormatMessage(JNIEnv *env, + jclass className, jint errorCode) { + LPVOID lpMsgBuf; + LPVOID lpDisplayBuf; + DWORD dw = (DWORD) errorCode; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, + NULL ); + + lpDisplayBuf = (LPVOID) LocalAlloc(LMEM_ZEROINIT, + (lstrlen((LPCTSTR) lpMsgBuf) + 40) * sizeof(TCHAR)); + StringCchPrintf((LPTSTR) lpDisplayBuf, + LocalSize(lpDisplayBuf) / sizeof(TCHAR), + TEXT("Failed with error %d: %s"), dw, lpMsgBuf); + return (jstring) (*env)->NewStringUTF(env, lpDisplayBuf); +} + +JNIEXPORT void JNICALL Java_pipe_Pipe_Print(JNIEnv *env, jclass className, + jstring lpMsgBuf) { + const jbyte *str; + str = (*env)->GetStringUTFChars(env, lpMsgBuf, NULL ); + if (str == NULL ) + return; + printf("Native: %s\n", str); + (*env)->ReleaseStringUTFChars(env, lpMsgBuf, str); + return; +} diff --git a/cpp/pipe/src/pipe.h b/cpp/pipe/src/pipe.h new file mode 100644 index 0000000..af398cb --- /dev/null +++ b/cpp/pipe/src/pipe.h @@ -0,0 +1,109 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class Pipes */ + +#ifndef _Included_pipe +#define _Included_pipe +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: Pipes + * Method: CreateNamedPipe + * Signature: (Ljava/lang/String;IIIIIII)I + */ +JNIEXPORT jint JNICALL Java_pipe_Pipe_CreateNamedPipe + (JNIEnv *, jclass, jstring, jint, jint, jint, jint, jint, jint, jint); + +/* + * Class: Pipes + * Method: ConnectNamedPipe + * Signature: (II)Z + */ +JNIEXPORT jboolean JNICALL Java_pipe_Pipe_ConnectNamedPipe + (JNIEnv *, jclass, jint, jint); + +/* + * Class: Pipes + * Method: GetLastError + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_pipe_Pipe_GetLastError + (JNIEnv *, jclass); + +/* + * Class: Pipes + * Method: CloseHandle + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_pipe_Pipe_CloseHandle + (JNIEnv *, jclass, jint); + +/* + * Class: Pipes + * Method: ReadFile + * Signature: (II)[B + */ +JNIEXPORT jbyteArray JNICALL Java_pipe_Pipe_ReadFile + (JNIEnv *, jclass, jint, jint); + +/* + * Class: Pipes + * Method: WriteFile + * Signature: (I[BI)I + */ +JNIEXPORT jint JNICALL Java_pipe_Pipe_WriteFile + (JNIEnv *, jclass, jint, jbyteArray, jint); + +/* + * Class: Pipes + * Method: FlushFileBuffers + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_pipe_Pipe_FlushFileBuffers + (JNIEnv *, jclass, jint); + +/* + * Class: Pipes + * Method: DisconnectNamedPipe + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_pipe_Pipe_DisconnectNamedPipe + (JNIEnv *, jclass, jint); + +/* + * Class: Pipes + * Method: CreateFile + * Signature: (Ljava/lang/String;IIIIII)I + */ +JNIEXPORT jint JNICALL Java_pipe_Pipe_CreateFile + (JNIEnv *, jclass, jstring, jint, jint, jint, jint, jint, jint); + +/* + * Class: Pipes + * Method: WaitNamedPipe + * Signature: (Ljava/lang/String;I)Z + */ +JNIEXPORT jboolean JNICALL Java_pipe_Pipe_WaitNamedPipe + (JNIEnv *, jclass, jstring, jint); + +/* + * Class: Pipes + * Method: FormatMessage + * Signature: (I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_pipe_Pipe_FormatMessage + (JNIEnv *, jclass, jint); + +/* + * Class: Pipes + * Method: Print + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_pipe_Pipe_Print + (JNIEnv *, jclass, jstring); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/java/pipe.dll b/java/pipe.dll new file mode 100644 index 0000000..f0ee87e Binary files /dev/null and b/java/pipe.dll differ diff --git a/java/settings.gradle b/java/settings.gradle index 64c3439..7d41c41 100644 --- a/java/settings.gradle +++ b/java/settings.gradle @@ -1 +1 @@ -include "base", "mimis", "wiiusej", "wiigee", "itunescontroller" \ No newline at end of file +include "base", "mimis", "wiiusej", "wiigee", "itunescontroller", "sound" \ No newline at end of file diff --git a/java/sound/.classpath b/java/sound/.classpath new file mode 100644 index 0000000..4828d2a --- /dev/null +++ b/java/sound/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/java/sound/.gitignore b/java/sound/.gitignore new file mode 100644 index 0000000..a4bf388 --- /dev/null +++ b/java/sound/.gitignore @@ -0,0 +1,3 @@ +/bin +/.settings +/sound diff --git a/java/sound/.project b/java/sound/.project new file mode 100644 index 0000000..87072b8 --- /dev/null +++ b/java/sound/.project @@ -0,0 +1,18 @@ + + + java.sound + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.springsource.ide.eclipse.gradle.core.nature + org.eclipse.jdt.core.javanature + + diff --git a/java/sound/build.gradle b/java/sound/build.gradle new file mode 100644 index 0000000..c758e85 --- /dev/null +++ b/java/sound/build.gradle @@ -0,0 +1,12 @@ +dependencies { + compile project(':base') + + compile 'commons-io:commons-io:2.+' + compile 'commons-cli:commons-cli:1.+' + compile 'commons-pool:commons-pool:1.+' + compile 'org.slf4j:slf4j-api:1.+' + compile 'org.slf4j:slf4j-log4j12:1.7.5' + compile 'org.ostermiller:utils:1.+' + compile 'com.googlecode.soundlibs:jlayer:1.+' + compile 'net.sf.javamusictag:jid3lib:0.+' +} \ No newline at end of file diff --git a/java/sound/build.xml b/java/sound/build.xml new file mode 100644 index 0000000..dbf0eb1 --- /dev/null +++ b/java/sound/build.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/sound/lame.exe b/java/sound/lame.exe new file mode 100644 index 0000000..7e69522 Binary files /dev/null and b/java/sound/lame.exe differ diff --git a/java/sound/launch4j.xml b/java/sound/launch4j.xml new file mode 100644 index 0000000..548e148 --- /dev/null +++ b/java/sound/launch4j.xml @@ -0,0 +1,22 @@ + + false + gui + stream.jar + stream.exe + + + + normal + http://java.com/download + + false + false + + + + + 1.6.0 + + preferJre + + \ No newline at end of file diff --git a/java/sound/libgomp-1.dll b/java/sound/libgomp-1.dll new file mode 100644 index 0000000..f4afc3e Binary files /dev/null and b/java/sound/libgomp-1.dll differ diff --git a/java/sound/libmad.dll b/java/sound/libmad.dll new file mode 100644 index 0000000..98730c5 Binary files /dev/null and b/java/sound/libmad.dll differ diff --git a/java/sound/libmp3lame.dll b/java/sound/libmp3lame.dll new file mode 100644 index 0000000..719126b Binary files /dev/null and b/java/sound/libmp3lame.dll differ diff --git a/java/sound/pipe.dll b/java/sound/pipe.dll new file mode 100644 index 0000000..8a948e6 Binary files /dev/null and b/java/sound/pipe.dll differ diff --git a/java/sound/play.exe b/java/sound/play.exe new file mode 100644 index 0000000..e3382ea Binary files /dev/null and b/java/sound/play.exe differ diff --git a/java/sound/pthreadgc2.dll b/java/sound/pthreadgc2.dll new file mode 100644 index 0000000..f64cc52 Binary files /dev/null and b/java/sound/pthreadgc2.dll differ diff --git a/java/sound/sox.exe b/java/sound/sox.exe new file mode 100644 index 0000000..e3382ea Binary files /dev/null and b/java/sound/sox.exe differ diff --git a/java/sound/soxi.exe b/java/sound/soxi.exe new file mode 100644 index 0000000..e3382ea Binary files /dev/null and b/java/sound/soxi.exe differ diff --git a/java/sound/src/main/java/old/Converter.java b/java/sound/src/main/java/old/Converter.java new file mode 100644 index 0000000..ab6f405 --- /dev/null +++ b/java/sound/src/main/java/old/Converter.java @@ -0,0 +1,187 @@ +package old; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import sound.util.Utils; +import javazoom.jl.decoder.Bitstream; +import javazoom.jl.decoder.BitstreamException; +import base.exception.worker.ActivateException; +import base.exception.worker.DeactivateException; +import base.worker.Worker; + +import com.Ostermiller.util.CircularByteBuffer; + +public class Converter extends Worker { + public static final String COMMAND = "lame --mp3input --cbr %s - - --quiet"; + public static final int BYTES = 4096; // bytes + public static final int BUFFER = 30000; // milliseconds + public static final int BUFFERING = 1000; // milliseconds + + protected int targetRate; + protected int rate; + protected int buffer; + protected boolean convert; + + protected Process process; + protected InputStream sourceInputStream, processInputStream, inputStream; + protected OutputStream processOutputStream; + protected CircularByteBuffer circularByteBuffer; + protected BufferWorker bufferWorker; + + public Converter(InputStream inputStream) { + this(inputStream, -1); + } + + public Converter(InputStream inputStream, int targetRate) { + this.sourceInputStream = inputStream; + this.targetRate = targetRate; + bufferWorker = new BufferWorker(); + convert = false; + } + + public void exit() { + super.exit(); + bufferWorker.exit(); + } + + public synchronized void activate() throws ActivateException { + /* Read bitrate */ + BufferedInputStream bufferedInputStream = new BufferedInputStream(sourceInputStream); + Bitstream bitStream = new Bitstream(bufferedInputStream); + try { + rate = bitStream.readFrame().bitrate() / 1000; + buffer = BUFFER * rate / 8; + } catch (BitstreamException e) { + logger.error("", e); + throw new ActivateException(); + } + + /* Check for need to convert */ + if (targetRate < 0 || rate == targetRate) { + logger.debug("No conversion required"); + inputStream = sourceInputStream; + } else { + logger.debug("Converting from " + rate + "kbps to " + targetRate + "kbps"); + try { + String command = String.format(COMMAND, rate > targetRate ? "-B " + targetRate : "-F -b " + targetRate); + logger.debug("Starting process: " + command); + process = Runtime.getRuntime().exec(command); + processInputStream = process.getInputStream(); + processOutputStream = process.getOutputStream(); + + /* Buffer output */ + circularByteBuffer = new CircularByteBuffer(CircularByteBuffer.INFINITE_SIZE); + inputStream = circularByteBuffer.getInputStream(); + bufferWorker.start(); + convert = true; + } catch (IOException e) { + logger.error("", e); + throw new ActivateException(); + } + } + super.activate(); + notifyAll(); + } + + protected void deactivate() throws DeactivateException { + super.deactivate(); + try { + sourceInputStream.close(); + bufferWorker.stop(); + if (convert) { + circularByteBuffer.clear(); + convert = false; + } + inputStream.close(); + } catch (IOException e) { + logger.error("", e); + throw new DeactivateException(); + } + } + + protected void work() { + if (!convert) { + try { + synchronized (this) { + wait(); + } + } catch (InterruptedException e) { + logger.error("", e); + } + return; + } + byte[] bytes = new byte[BYTES]; + int read = 0; + try { + logger.debug("Writing input to process"); + while ((read = sourceInputStream.read(bytes)) > 0 && !deactivate) { + /* Limit buffer size */ + while (inputStream.available() > buffer) { + int progress = (int) ((1 - (inputStream.available() - buffer) / (float) buffer) * 100); + logger.trace("Waiting for buffer to empty: " + progress + "%"); + sleep(BUFFERING); + } + processOutputStream.write(bytes, 0, read); + } + processOutputStream.close(); + logger.debug("Stopped writing input to process"); + process.waitFor(); + logger.debug("Process finished"); + } catch (IOException e) { + } catch (InterruptedException e) { + logger.error("", e); + } + stop(); + } + + public synchronized InputStream getInputStream() { + if (!active()) { + if (!activate) { + start(); + } + try { + wait(); + } catch (InterruptedException e) { + logger.error("", e); + } + } + return inputStream; + } + + public synchronized void setInputStream(InputStream inputStream) { + this.inputStream = inputStream; + } + + class BufferWorker extends Worker { + protected void work() { + byte[] bytes = new byte[BYTES]; + int read = 0; + try { + OutputStream bufferOutputStream = circularByteBuffer.getOutputStream(); + logger.debug("Start buffering process output"); + while ((read = processInputStream.read(bytes, 0, BYTES)) > 0) { + bufferOutputStream.write(bytes, 0, read); + } + logger.debug("Finished buffering process output"); + bufferOutputStream.close(); + } catch (IOException e) {} + stop(); + } + } + + public static void main(String[] args) { + Mp3 mp3 = new Mp3(new File("stream.mp3"), 128); + InputStream inputStream = mp3.getInputStream(); + + /* Play */ + //Utils.play(inputStream); + + /* Write to file */ + Utils.write(inputStream, new File("output.mp3")); + mp3.exit(); + } +} diff --git a/java/sound/src/main/java/old/List.java b/java/sound/src/main/java/old/List.java new file mode 100644 index 0000000..c475277 --- /dev/null +++ b/java/sound/src/main/java/old/List.java @@ -0,0 +1,198 @@ +package old; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Scanner; + +import base.exception.worker.ActivateException; +import base.worker.Worker; + +import com.Ostermiller.util.BufferOverflowException; +import com.Ostermiller.util.CircularByteBuffer; +import com.Ostermiller.util.CircularObjectBuffer; + +public class List extends Worker { + public static final int STEP = 80; // milliseconds + public static final int RATE = 192; // kbps + public static final int OVERLAP = 20000; // milliseconds + + protected File file; + protected String[] fileArray; + + protected int rate; + protected int chunk; + protected int overlap; + protected byte[] bytes; + protected boolean next; + protected Mp3 mp3, nextMp3; + + protected InputStream mp3InputStream; + protected OutputStream audioOutputStream; + protected CircularByteBuffer circularByteBuffer; + protected CircularObjectBuffer circularStringBuffer; + + public List(File file) { + this(file, RATE); + } + + public List(File file, int rate) { + this.file = file; + this.rate = rate; + chunk = STEP * rate / 8; + overlap = OVERLAP * RATE / 8; + bytes = new byte[chunk]; + next = true; + } + + public void exit() { + super.exit(); + if (mp3 != null) { + mp3.exit(); + } + if (nextMp3 != null) { + nextMp3.exit(); + } + } + + protected synchronized void activate() throws ActivateException { + try { + Scanner scanner = new Scanner(file); + ArrayList fileList = new ArrayList(); + while (scanner.hasNextLine()) { + fileList.add(scanner.nextLine()); + } + if (fileList.size() > 0) { + fileArray = fileList.toArray(new String[0]); + + circularByteBuffer = new CircularByteBuffer(CircularByteBuffer.INFINITE_SIZE); + audioOutputStream = circularByteBuffer.getOutputStream(); + + circularStringBuffer = new CircularObjectBuffer(CircularByteBuffer.INFINITE_SIZE); + setNext(); + super.activate(); + notifyAll(); + return; + } + } catch (FileNotFoundException e) { + logger.error("", e); + } + throw new ActivateException(); + } + + protected synchronized void work() { + try { + int left = chunk; + while (left > 0) { + /* Check for need to load next mp3 */ + int available = mp3InputStream == null ? -1 : mp3InputStream.available(); + boolean expect = mp3 == null ? false : mp3.active(); + + /* Act when no more data is expected */ + if (!expect) { + if (available < overlap) { + setNext(); + next = false; + nextMp3.start(); + } + if (available < 1) { + swap(); + } + } + + /* Transfer data */ + int read = mp3InputStream.read(bytes, 0, left); + left -= read; + audioOutputStream.write(bytes, 0, read); + } + } catch (IOException e) { + /* Swap to next if stream has stopped */ + setNext(); + swap(); + } catch (IllegalStateException e) { + logger.error("", e); + } + sleep(STEP); + } + + protected File getRandomFile() { + return new File(fileArray[(int) (Math.random() * fileArray.length)]); + } + + public synchronized void setNext() { + if (nextMp3 == null) { + logger.debug("Initialize next mp3"); + nextMp3 = new Mp3(getRandomFile(), rate); + } else if (next) { + logger.debug("Load next mp3"); + nextMp3.setFile(getRandomFile()); + } + } + + public synchronized void next() { + logger.debug("Stop current mp3"); + mp3.stop(); + } + + public void swap() { + logger.debug("Swap to next mp3"); + Mp3 swapMp3 = mp3; + mp3 = nextMp3; + nextMp3 = swapMp3; + next = true; + + /* Swap stream and announce title */ + mp3InputStream = mp3.getInputStream(); + try { + circularStringBuffer.write(mp3.getTitle()); + } catch (BufferOverflowException e) { + logger.error("", e); + } catch (IllegalStateException e) { + logger.error("", e); + } catch (InterruptedException e) { + logger.error("", e); + } + } + + public synchronized InputStream getInputStream() { + if (circularByteBuffer == null) { + start(); + try { + wait(); + } catch (InterruptedException e) { + logger.error("", e); + } + } + return circularByteBuffer.getInputStream(); + } + + public synchronized CircularObjectBuffer getMetaBuffer() { + if (circularStringBuffer == null) { + start(); + try { + wait(); + } catch (InterruptedException e) { + logger.error("", e); + } + } + return circularStringBuffer; + } + + public static void main(String[] args) { + int rate = 192; + List list = new List(new File("mp3"), rate); + /*Shoutcast shoutcast = new Shoutcast(null, rate, 9876); + shoutcast.start(); + shoutcast.setInputStream(list.getInputStream()); + shoutcast.setMetaBuffer(list.getMetaBuffer());*/ + while (true) { + try { + Thread.sleep(15000); + list.next(); + } catch (InterruptedException e) {} + } + } +} diff --git a/java/sound/src/main/java/old/Mp3.java b/java/sound/src/main/java/old/Mp3.java new file mode 100644 index 0000000..589d35e --- /dev/null +++ b/java/sound/src/main/java/old/Mp3.java @@ -0,0 +1,80 @@ +package old; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +import org.farng.mp3.MP3File; +import org.farng.mp3.TagException; + +import sound.util.Utils; +import base.exception.worker.ActivateException; + +public class Mp3 extends Converter { + protected File file; + protected String title; + + public Mp3(File file) { + this(file, -1); + } + + public Mp3(File file, int targetRate) { + super(null, targetRate); + setFile(file); + title = ""; + } + + public synchronized void activate() throws ActivateException { + /* Open file */ + try { + sourceInputStream = new FileInputStream(file); + } catch (FileNotFoundException e) { + logger.error("", e); + throw new ActivateException(); + } + + /* Read ID3V2 tags */ + try { + MP3File mp3File = new MP3File(file); + String album = clean(mp3File.getID3v2Tag().getAlbumTitle()); + String artist = clean(mp3File.getID3v2Tag().getLeadArtist()); + String track = clean(mp3File.getID3v2Tag().getSongTitle()); + if (album.isEmpty()) { + title = String.format("%s - %s", artist, track, album); + } else { + title = String.format("%s - %s {%s}", artist, track, album); + } + logger.debug("Title: " + title); + } catch (IOException e) { + logger.error("", e); + } catch (TagException e) { + logger.error("", e); + } + try { + sourceInputStream.skip(100000); + } catch (IOException e) {} + super.activate(); + } + + protected String clean(String input) { + String output = input.replace("\0", ""); + return output.replace("ÿþ", ""); + } + + public String getTitle() { + return title; + } + + public void setFile(File file) { + this.file = file; + } + + public static void main(String[] args) { + final Mp3 mp3 = new Mp3(new File("input.mp3"), 128); + Utils.write(mp3.getInputStream(), new File("one.mp3")); + mp3.setFile(new File("stream.mp3")); + Utils.write(mp3.getInputStream(), new File("two.mp3")); + mp3.exit(); + } +} diff --git a/java/sound/src/main/java/old/Transducer.java b/java/sound/src/main/java/old/Transducer.java new file mode 100644 index 0000000..e4ed4a6 --- /dev/null +++ b/java/sound/src/main/java/old/Transducer.java @@ -0,0 +1,46 @@ +package old; + +import java.io.InputStream; + +import sound.Consumer; +import sound.Producer; + +public class Transducer implements Consumer, Producer { + public int rate; + + public Transducer(Producer producer) { + //setProducer(producer); + } + + public int getRate() { + return rate; + } + + public InputStream getInputStream() { + // TODO Auto-generated method stub + return null; + } + + public void start(Producer producer) { + // TODO Auto-generated method stub + + } + + @Override + public void start() { + // TODO Auto-generated method stub + + } + + @Override + public void stop() { + // TODO Auto-generated method stub + + } + + @Override + public void exit() { + // TODO Auto-generated method stub + + } +} diff --git a/java/sound/src/main/java/pipe/Client.java b/java/sound/src/main/java/pipe/Client.java new file mode 100644 index 0000000..b36d882 --- /dev/null +++ b/java/sound/src/main/java/pipe/Client.java @@ -0,0 +1,24 @@ +package pipe; + +import java.io.RandomAccessFile; + +public class Client { + public static void main(String[] args) { + try { + // Connect to the pipe + RandomAccessFile pipe = new RandomAccessFile("\\\\.\\pipe\\detest", "rw"); + String echoText = "Hello word\n"; + + // write to pipe + pipe.write(echoText.getBytes()); + + // read response + String echoResponse = pipe.readLine(); + System.out.println(echoResponse); + pipe.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/java/sound/src/main/java/pipe/Pipe.java b/java/sound/src/main/java/pipe/Pipe.java new file mode 100644 index 0000000..c74b90f --- /dev/null +++ b/java/sound/src/main/java/pipe/Pipe.java @@ -0,0 +1,54 @@ +package pipe; + +/** + * @author Vikram S Khatri vikram.khatri@us.ibm.com + */ +public class Pipe { + static final int ERROR_PIPE_CONNECTED = 535; + static final int ERROR_BROKEN_PIPE = 109; + static final int PIPE_ACCESS_DUPLEX = 0x00000003; + static final int PIPE_WAIT = 0x00000000; + + static { + System.loadLibrary("pipe"); + } + + public static final native int CreateNamedPipe( + String pipeName, + int ppenMode, + int pipeMode, + int maxInstances, + int outBufferSize, + int inBufferSize, + int defaultTimeOut, + int securityAttributes); + + public static final native boolean ConnectNamedPipe(int namedPipeHandle, int overlapped); + + public static final native int GetLastError(); + + public static final native boolean CloseHandle(int bbject); + + public static final native byte[] ReadFile(int file, int numberOfBytesToRead); + + public static final native int WriteFile(int file, byte[] buffer, int numberOfBytesToWrite); + + public static final native boolean FlushFileBuffers(int file); + + public static final native boolean DisconnectNamedPipe(int namedPipeHandle); + + public static final native int CreateFile( + String fileName, + int desiredAccess, + int shareMode, + int securityAttributes, + int creationDisposition, + int flagsAndAttributes, + int templateFile); + + public static final native boolean WaitNamedPipe(String namedPipeName, int timeOut); + + public static final native String FormatMessage(int errorCode); + + public static final native void Print(String message); +} diff --git a/java/sound/src/main/java/pipe/TestPipe.java b/java/sound/src/main/java/pipe/TestPipe.java new file mode 100644 index 0000000..b1e1e32 --- /dev/null +++ b/java/sound/src/main/java/pipe/TestPipe.java @@ -0,0 +1,87 @@ +package pipe; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +public class TestPipe { + + private int namedPipeHandle; + private String pipeName, srcFile; + private int pipeBuffer = 131072, fileBuffer = 8192; + + public TestPipe(String pipeName, String srcFile) { + this.pipeName = pipeName; + this.srcFile = srcFile; + } + + private void log(String message) { + System.out.println(message); + } + + private boolean createPipe() { + namedPipeHandle = Pipe.CreateNamedPipe( + pipeName, + Pipe.PIPE_ACCESS_DUPLEX, + Pipe.PIPE_WAIT, + 5, + pipeBuffer, + pipeBuffer, + 0xffffffff, + 0); + if (namedPipeHandle == -1) { + log("CreateNamedPipe failed for " + pipeName + " for error Message " + Pipe.FormatMessage(Pipe.GetLastError())); + } else { + log("Named Pipe " + pipeName + " created successfully Handle=" + namedPipeHandle); + } + return namedPipeHandle != -1; + } + + private boolean connectToPipe() { + log("Waiting for a client to connect to pipe " + pipeName); + boolean connected = Pipe.ConnectNamedPipe(namedPipeHandle, 0); + if (!connected) { + int lastError = Pipe.GetLastError(); + if (lastError == Pipe.ERROR_PIPE_CONNECTED) + connected = true; + } + log((connected ? "Connected to the pipe " : "Falied to connect to the pipe ") + pipeName); + return connected; + } + + public void runPipe() { + if (createPipe() && connectToPipe()) { + log("Client connected."); + try { + File f1 = new File(this.srcFile); + InputStream in = new FileInputStream(f1); + log("Sending data to the pipe"); + byte[] buf = new byte[fileBuffer]; + int len, bytesWritten; + while ((len = in.read(buf)) > 0) { + bytesWritten = Pipe.WriteFile(namedPipeHandle, buf, len); + log("Sent " + len + "/" + bytesWritten + " bytes to the pipe"); + if (bytesWritten == -1) { + int errorNumber = Pipe.GetLastError(); + log("Error Writing to pipe " + Pipe.FormatMessage(errorNumber)); + } + } + in.close(); + Pipe.FlushFileBuffers(namedPipeHandle); + Pipe.CloseHandle(namedPipeHandle); + Pipe.DisconnectNamedPipe(namedPipeHandle); + log("Writing to the pipe completed."); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + String pipeName = "\\\\.\\pipe\\detest"; + String fileName = "txt/bla.txt"; + //fileName = "C:\\Users\\Rik\\Music\\Artists\\+44\\When Your Heart Stops Beating\\+44 - 155.mp3"; + TestPipe testPipe = new TestPipe(pipeName, fileName); + testPipe.runPipe(); + } +} diff --git a/java/sound/src/main/java/sound/Consumer.java b/java/sound/src/main/java/sound/Consumer.java new file mode 100644 index 0000000..9174078 --- /dev/null +++ b/java/sound/src/main/java/sound/Consumer.java @@ -0,0 +1,7 @@ +package sound; + +public interface Consumer { + public void start(Producer producer); + public void stop(); + public void exit(); +} diff --git a/java/sound/src/main/java/sound/Format.java b/java/sound/src/main/java/sound/Format.java new file mode 100644 index 0000000..c24c3d3 --- /dev/null +++ b/java/sound/src/main/java/sound/Format.java @@ -0,0 +1,13 @@ +package sound; + +import javax.sound.sampled.AudioFormat; + +public interface Format extends Cloneable { + public interface Standard extends Format { + public AudioFormat getAudioFormat(); + } + + public interface Mp3 extends Format { + public int getRate(); + } +} \ No newline at end of file diff --git a/java/sound/src/main/java/sound/Producer.java b/java/sound/src/main/java/sound/Producer.java new file mode 100644 index 0000000..c25eb48 --- /dev/null +++ b/java/sound/src/main/java/sound/Producer.java @@ -0,0 +1,10 @@ +package sound; + +import java.io.InputStream; + +public interface Producer extends Format { + public InputStream getInputStream(); + public void start(); + public void stop(); + public void exit(); +} \ No newline at end of file diff --git a/java/sound/src/main/java/sound/Source.java b/java/sound/src/main/java/sound/Source.java new file mode 100644 index 0000000..8fcf427 --- /dev/null +++ b/java/sound/src/main/java/sound/Source.java @@ -0,0 +1,161 @@ +package sound; + +import java.io.IOException; +import java.io.InputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; + +import javazoom.jl.decoder.JavaLayerException; +import javazoom.jl.player.Player; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sound.util.Tool; +import base.exception.worker.ActivateException; +import base.exception.worker.DeactivateException; +import base.worker.Worker; + +public class Source implements Consumer { + protected Logger logger = LoggerFactory.getLogger(getClass()); + + protected static final int BUFFER_SIZE = 1024 * 4; // in bytes + protected static final int FRAMES = 10; // count + + protected String name; + protected Producer producer; + protected InputStream producerInputStream; + protected Worker worker; + + public Source(String name) throws LineUnavailableException { + this.name = name; + } + + public void start() { + if (worker != null) { + worker.start(true); + } + } + + public void start(Producer producer) { + this.producer = producer; + producerInputStream = producer.getInputStream(); + if (worker != null) { + worker.exit(); + } + if (producer instanceof Format.Standard) { + logger.debug("Format.Standard"); + worker = new DefaultWorker((Format.Standard) producer); + } else if (producer instanceof Format.Mp3) { + logger.debug("Format.Mp3"); + worker = new Mp3Worker((Format.Mp3) producer); + } + start(); + } + + public void stop() { + if (worker != null) { + worker.stop(); + } + } + + public void exit() { + if (worker != null) { + worker.exit(); + } + } + + protected class DefaultWorker extends Worker { + protected Format.Standard format; + protected SourceDataLine line; + + public DefaultWorker(Format.Standard format) { + this.format = format; + } + + public void activate() throws ActivateException { + AudioFormat audioFormat = format.getAudioFormat(); + try { + if (line == null) { + line = Tool.getSourceDataLine(name, audioFormat); + } + if (!line.isOpen()) { + line.open(); + } + } catch (LineUnavailableException e) { + logger.error("", e); + throw new ActivateException(); + } + if (!line.isRunning()) { + line.start(); + } + super.activate(); + } + + public void deactivate() throws DeactivateException { + super.deactivate(); + line.flush(); + } + + public void exit() { + super.exit(); + line.close(); + } + + protected void work() { + try { + byte[] buffer = new byte[BUFFER_SIZE]; + int read = producerInputStream.read(buffer, 0, buffer.length); + if (read > 0) { + line.write(buffer, 0, read); + } else { + exit(); + } + } catch (IOException e) { + logger.error("", e); + exit(); + } + } + } + + protected class Mp3Worker extends Worker { + protected Format.Mp3 format; + protected Player player; + + public Mp3Worker(Format.Mp3 format) { + this.format = format; + } + + public void activate() throws ActivateException { + producer.start(); + super.activate(); + } + + public void deactivate() throws DeactivateException { + super.deactivate(); + producer.stop(); + } + + public void exit() { + super.exit(); + player.close(); + } + + protected void work() { + try { + if (player == null) { + player = new Player(producerInputStream); + sleep(SLEEP); + } + player.play(FRAMES); + } catch (JavaLayerException e) { + logger.error("", e); + } + if (player.isComplete()) { + stop(); + } + } + } +} diff --git a/java/sound/src/main/java/sound/consumer/Port.java b/java/sound/src/main/java/sound/consumer/Port.java new file mode 100644 index 0000000..c39446a --- /dev/null +++ b/java/sound/src/main/java/sound/consumer/Port.java @@ -0,0 +1,121 @@ +package sound.consumer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.sound.sampled.AudioFormat; + +import sound.Consumer; +import sound.Format; +import sound.Format.Standard; +import sound.Producer; +import sound.util.SoxBuilder; +import sound.util.SoxBuilder.File; +import sound.util.SoxBuilder.File.Type; +import sound.util.SoxBuilder.Option; +import base.exception.worker.ActivateException; +import base.exception.worker.DeactivateException; +import base.worker.Worker; + +public class Port extends Worker implements Consumer { + protected static final int BUFFER_SIZE = 1024 * 4; // in bytes + + protected String device; + protected Producer producer; + protected Process process; + protected InputStream producerInputStream; + protected OutputStream processOutputStream; + protected ProcessBuilder processBuilder; + + public Port() { + this("0"); + } + + public Port(String device) { + this.device = device; + } + + public void start(Producer producer) { + start(producer, THREAD); + } + + @SuppressWarnings("static-access") + public void start(Producer producer, boolean thread) { + this.producer = producer; + producerInputStream = producer.getInputStream(); + + String command = ""; + if (producer instanceof Standard) { + AudioFormat audioFormat = ((Standard) producer).getAudioFormat(); + SoxBuilder.addFile(File.setType(Type.STANDARD).setOptions(audioFormat)); + } else if (producer instanceof Format.Mp3) { + SoxBuilder.addFile(File.setType(Type.STANDARD).setOption(File.Format.MP3)); + } + command = SoxBuilder + .setOption(Option.QUIET) + .addFile(File.setType(Type.DEVICE)) + .build(); + + logger.debug(String.format("Build process (\"%s\")", command)); + processBuilder = new ProcessBuilder(command.split(" ")); + processBuilder.environment().put("AUDIODEV", device); + + start(thread); + } + + protected void activate() throws ActivateException { + producer.start(); + if (process == null) { + try { + process = processBuilder.start(); + } catch (IOException e) { + logger.error("", e); + throw new ActivateException(); + } + processOutputStream = process.getOutputStream(); + } + super.activate(); + } + + protected void deactivate() throws DeactivateException { + super.deactivate(); + try { + processOutputStream.flush(); + } catch (IOException e) { + logger.error("", e); + throw new DeactivateException(); + } + } + + public void exit() { + try { + logger.debug("close process output stream"); + processOutputStream.close(); + + logger.debug("wait for process to terminate"); + process.waitFor(); + } catch (IOException e) { + logger.error("", e); + } catch (InterruptedException e) { + logger.error("", e); + } finally { + process = null; + } + } + + protected void work() { + try { + byte[] buffer = new byte[BUFFER_SIZE]; + int read = producerInputStream.read(buffer, 0, buffer.length); + if (read > 0) { + processOutputStream.write(buffer, 0, read); + } else { + exit(); + } + } catch (IOException e) { + logger.error("", e); + exit(); + } + } +} diff --git a/java/sound/src/main/java/sound/producer/Stream.java b/java/sound/src/main/java/sound/producer/Stream.java new file mode 100644 index 0000000..24500a8 --- /dev/null +++ b/java/sound/src/main/java/sound/producer/Stream.java @@ -0,0 +1,199 @@ +package sound.producer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.Socket; +import java.net.URL; + +import sound.Format; +import sound.Producer; +import sound.stream.HoardedInputStream; +import base.exception.worker.ActivateException; +import base.exception.worker.DeactivateException; +import base.worker.Worker; + +import com.Ostermiller.util.CircularByteBuffer; +import com.Ostermiller.util.CircularObjectBuffer; + +public class Stream extends Worker implements Producer, Format.Mp3 { + public static final int STEP = 80; // in milliseconds + + protected String http; + protected Socket socket; + protected InputStream socketInputStream; + protected OutputStreamWriter socketOutputStreamWriter; + protected HoardedInputStream hoardedInputStream; + protected int meta; + protected int rate; + protected int chunk; + protected int untilMeta; + protected CircularByteBuffer audioCircularByteBuffer; + protected CircularObjectBuffer metaCircularObjectBuffer; + protected String metaData; + + public Stream(String http) { + this.http = http; + meta = -1; + rate = -1; + audioCircularByteBuffer = new CircularByteBuffer(CircularByteBuffer.INFINITE_SIZE); + metaCircularObjectBuffer = new CircularObjectBuffer(); + } + + protected void connect(URL url) { + try { + /* Open socket communication */ + socket = new Socket(url.getHost(), url.getPort()); + socketInputStream = socket.getInputStream(); + socketOutputStreamWriter = new OutputStreamWriter(socket.getOutputStream()); + + /* Write stream request */ + if (url.getFile().equals("")) { + socketOutputStreamWriter.write("GET / HTTP/1.1\r\n"); + } else { + socketOutputStreamWriter.write("GET " + url.getFile() + " HTTP/1.1\r\n"); + } + socketOutputStreamWriter.write("Host: " + url.getHost() + "\r\n"); + //socketOutputStreamWriter.write("Icy-MetaData: 1\r\n"); + socketOutputStreamWriter.write("Connection: close\r\n"); + socketOutputStreamWriter.write("\r\n"); + socketOutputStreamWriter.flush(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + protected void activate() throws ActivateException { + try { + /* Initialize connection */ + URL url = new URL(http); + + /* Parse headers */ + connect(url); + InputStreamReader inputStreamReader = new InputStreamReader(socketInputStream); + StringBuffer stringBuffer = new StringBuffer(); + char character; + int skip = 0; + while ((character = (char) inputStreamReader.read()) > 0) { + ++skip; + if (character == '\n') { + /* Fetch relevant headers */ + String line = stringBuffer.toString().trim(); + if (line.startsWith("icy-metaint")) { + meta = Integer.valueOf(line.substring(line.indexOf(":") + 1).trim()); + } else if (line.startsWith("icy-br")) { + rate = Integer.valueOf(line.substring(line.indexOf(":") + 1).trim()); + } else if (line.equals("")) { + break; + } + stringBuffer = new StringBuffer(); + } else { + stringBuffer.append(character); + } + } + inputStreamReader.close(); + + /* Reconnect to bypass pre-buffering problems */ + connect(url); + socketInputStream = socket.getInputStream(); + socketInputStream.skip(skip); + } catch (IOException e) { + e.printStackTrace(); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + + /* Calculate streaming parameters */ + //untilMeta = meta; + chunk = STEP * rate / 8; + super.activate(); + } + + public void deactivate() throws DeactivateException { + super.deactivate(); + audioCircularByteBuffer.clear(); + metaCircularObjectBuffer.clear(); + try { + hoardedInputStream.clear(); + } catch (IOException e) { + logger.error("", e); + throw new DeactivateException(); + } + } + + protected void work() { + int left = chunk; + + /* Handle media at appropriate times * + while (meta > 0 && left >= untilMeta) { + stream(untilMeta); + left -= untilMeta; + meta(); + untilMeta = meta; + }*/ + + /* Stream at fixed rate */ + stream(left); + //untilMeta -= left; + sleep(STEP); + } + + protected void stream(int length) { + try { + byte[] bytes = new byte[length]; + int read = 0; + while (length > 0 && (read = socketInputStream.read(bytes)) > 0) { + length -= read; + audioCircularByteBuffer.getOutputStream().write(bytes); + } + } catch (IOException e) { + logger.error(e.getMessage()); + stop(); + } + } + + protected void meta() { + try { + /* Retrieve data length */ + byte[] data = new byte[1]; + socketInputStream.read(data); + + int length = 16 * data[0]; + data = new byte[length]; + socketInputStream.read(data); + + /* Check for new data */ + String newMetaData = new String(data); + if (!newMetaData.isEmpty() && !newMetaData.equals(metaData)) { + metaData = newMetaData; + metaCircularObjectBuffer.write(new String(data)); + logger.debug("data: " + metaData); + } + return; + } catch (IOException e) { + logger.error("", e); + } catch (IllegalStateException e) { + logger.error("", e); + } catch (InterruptedException e) { + logger.error("", e); + } + stop(); + return; + } + + public InputStream getInputStream() { + if (hoardedInputStream == null) { + hoardedInputStream = new HoardedInputStream(audioCircularByteBuffer.getInputStream()); + } + return hoardedInputStream; + } + + public CircularObjectBuffer getMetaBufferStream() { + return metaCircularObjectBuffer; + } + + public int getRate() { + return rate; + } +} diff --git a/java/sound/src/main/java/sound/producer/Target.java b/java/sound/src/main/java/sound/producer/Target.java new file mode 100644 index 0000000..e752e5d --- /dev/null +++ b/java/sound/src/main/java/sound/producer/Target.java @@ -0,0 +1,97 @@ +package sound.producer; + +import java.io.IOException; +import java.io.InputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.TargetDataLine; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sound.Format; +import sound.Producer; +import sound.stream.HoardedInputStream; +import sound.util.Tool; + +public class Target implements Producer, Format.Standard { + protected Logger logger = LoggerFactory.getLogger(getClass()); + + protected Standard format; + + protected TargetDataLine line; + protected InputStream targetInputStream; + protected HoardedInputStream hoardedInputStream; + + protected AudioFormat audioFormat; + + public Target(String name) throws LineUnavailableException { + logger.debug(String.format("Target \"%s\" without format", name)); + line = Tool.getTargetDataLine(name); + audioFormat = line.getFormat(); + targetInputStream = new TargetInputStream(); + } + + public Target(String name, AudioFormat audioFormat) throws LineUnavailableException { + logger.debug(String.format("Target \"%s\" with format: %s", name, audioFormat)); + this.audioFormat = audioFormat; + line = Tool.getTargetDataLine(name, audioFormat); + targetInputStream = new TargetInputStream(); + } + + public AudioFormat getAudioFormat() { + return audioFormat; + } + + public InputStream getInputStream() { + return targetInputStream; + } + + public class TargetInputStream extends InputStream { + protected boolean open; + + public TargetInputStream() { + open = false; + } + + public int read() throws IOException { + start(); + byte[] buffer = new byte[1]; + line.read(buffer, 0, 1); + return (int) buffer[0]; + } + + public int read(byte[] buffer, int offset, int length) { + start(); + line.read(buffer, offset, length); + return length; + } + + public int available() { + start(); + return line.available(); + } + } + + public void start() { + if (!line.isOpen()) { + try { + line.open(); + } catch (LineUnavailableException e) { + logger.error("", e); + } + } + if (!line.isRunning()) { + line.start(); + } + } + + public void stop() { + line.flush(); + } + + public void exit() { + line.close(); + } +} diff --git a/java/sound/src/main/java/sound/stream/HoardedInputStream.java b/java/sound/src/main/java/sound/stream/HoardedInputStream.java new file mode 100644 index 0000000..beb941c --- /dev/null +++ b/java/sound/src/main/java/sound/stream/HoardedInputStream.java @@ -0,0 +1,76 @@ +package sound.stream; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HoardedInputStream extends BufferedInputStream { + protected Logger logger = LoggerFactory.getLogger(getClass()); + + protected static final int SLEEP = 500; // in milliseconds + protected static final int BUFFER_SIZE = 30000; // in bytes + protected static final int MINIMUM_SIZE = 1000; // in bytes + + protected int bufferSize; + protected int minimumSize; + protected boolean hoard; + + public HoardedInputStream(InputStream inputStream) { + this(inputStream, BUFFER_SIZE, MINIMUM_SIZE); + } + + public HoardedInputStream(InputStream inputStream, int bufferSize) { + super(inputStream, bufferSize); + this.bufferSize = bufferSize; + hoard = true; + } + + public HoardedInputStream(InputStream inputStream, int bufferSize, int minimumSize) { + this(inputStream, bufferSize); + this.minimumSize = minimumSize; + } + + public int read() throws IOException { + hoard(); + byte[] buffer = new byte[1]; + in.read(buffer, 0, 1); + return (int) buffer[0]; + } + + public int read(byte[] buffer, int offset, int length) throws IOException { + hoard(); + in.read(buffer, offset, length); + return length; + } + + public void hoard() throws IOException { + int available = available(); + if (hoard && available < MINIMUM_SIZE) { + long time = System.currentTimeMillis(); + do { + try { + Thread.sleep(SLEEP); + } catch (InterruptedException e) { + logger.warn("", e); + } + } while (available() < BUFFER_SIZE); + logger.debug(String.format("Buffered %d bytes in %s milliseconds", BUFFER_SIZE - available, System.currentTimeMillis() - time)); + } + } + + public void clear() throws IOException { + this.buf = new byte[buf.length]; + reset(); + } + + public void drain() { + drain(true); + } + + public void drain(boolean drain) { + hoard = !drain; + } +} diff --git a/java/sound/src/main/java/sound/util/SoxBuilder.java b/java/sound/src/main/java/sound/util/SoxBuilder.java new file mode 100644 index 0000000..9870d50 --- /dev/null +++ b/java/sound/src/main/java/sound/util/SoxBuilder.java @@ -0,0 +1,321 @@ +package sound.util; + +import java.util.HashMap; +import java.util.Map.Entry; + +import javax.sound.sampled.AudioFormat; + +import sound.util.SoxBuilder.Option.Combine; +import sound.util.SoxBuilder.Option.Replay; + +public final class SoxBuilder { + protected static SoxBuilder instance; + protected static HashMap optionMap; + protected static String files; + protected static String effects; + + static { + instance = new SoxBuilder(); + reset(); + } + + public static void reset() { + optionMap = new HashMap(); + files = ""; + effects = ""; + } + + public static SoxBuilder setOption(Option option, String value) { + optionMap.put(option.getCode(), value); + return instance; + } + + public static SoxBuilder setOption(Option option) { + return SoxBuilder.setOption(option, ""); + } + + public static SoxBuilder setOption(Option option, int value) { + return SoxBuilder.setOption(option, String.valueOf(value)); + } + + public static SoxBuilder setOption(Option option, Combine combine) { + return SoxBuilder.setOption(option, combine.getCode()); + } + + public static SoxBuilder setOption(Combine combine) { + return SoxBuilder.setOption(Option.COMBINE, combine); + } + + public static SoxBuilder setOption(Option option, Replay replay) { + return SoxBuilder.setOption(option, replay.toString().toLowerCase()); + } + + public static SoxBuilder setOption(Replay replay) { + return SoxBuilder.setOption(Option.REPLAY, replay); + } + + public static SoxBuilder addFile(File file) { + files = String.format("%s %s", files, file.build()); + return instance; + } + + public static SoxBuilder addEffect(Effect effect) { + effects = String.format("%s %s", effects, effect.build()); + return instance; + } + + public String build() { + String build = "sox"; + for (Entry entry : optionMap.entrySet()) { + String value = entry.getValue(); + if (value.equals("")) { + build = String.format("%s %s", build, entry.getKey()); + } else { + String option = String.format("%s %s", entry.getKey(), value); + build = String.format("%s %s", build, option); + } + } + build = String.format("%s%s%s", build, files, effects); + reset(); + return build; + } + + public enum Environment { + AUDIODRIVER, AUDIODEV + } + + public enum Option { + BUFFER ("--buffer"), // default=8192 + INPUT_BUFFER ("--input-buffer"), + CLOBBER ("--clobber"), + COMBINE ("--combine"), // |Combine| + NO_DITHER ("--no-dither"), // (-D) + EFFECTS_FILE ("--efects-file"), + GUARD ("--guard"), // (-G) + MIX ("-m"), // (--combine mix) + MERGE ("-M"), // (--combine merge) + MAGIC ("--magic"), + MULTI_THREADED ("--multi-threaded"), + SINGLE_THREADED ("--single-threaded"), + NORM ("--norm"), // [=dB-level] + PLAY_RATE_ARG ("--play-rate-arg"), + QUIET ("--no-show-progress"), // (-q) + REPEATABLE ("-R"), + REPLAY ("--replay-gain"), // |Replay| + MULTIPLY ("-T"), // (--combine multiply) + TEMP ("--temp"); + + protected String code; + + private Option(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + + public enum Combine { + CONCATENATE ("concatenate"), + MERGE ("merge"), // (-M) + MIX ("mix"), // (-m) + MIX_POWER ("mix-power"), + MULTIPLY ("multiply"), // (-T) + SEQUENCE ("sequence"); + + protected String code; + + private Combine(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + } + + public enum Replay { + TRACK, ALBUM, OFF + } + } + + public static class File { + protected static File instance; + + protected static HashMap optionMap; + protected static Type type; + + static { + instance = new File(); + reset(); + } + + public static void reset() { + optionMap = new HashMap(); + type = Type.PIPE; + } + + public static File setOption(Option option, String value) { + optionMap.put(option.getCode(), value); + return instance; + } + + public static File setOption(Option option) { + return File.setOption(option, ""); + } + + public static File setOption(Option option, int value) { + return File.setOption(option, String.valueOf(value)); + } + + public static File setOption(Option option, Encoding encoding) { + return File.setOption(option, encoding.getCode()); + } + + public static File setOption(Encoding encoding) { + return File.setOption(Option.ENCODING, encoding); + } + + public static File setOption(Option option, Format format) { + return File.setOption(option, format.toString().toLowerCase()); + } + + public static File setOption( Format format) { + return File.setOption(Option.FORMAT, format); + } + + public static File setOption(Option option, Endian endian) { + return File.setOption(option, endian.toString().toLowerCase()); + } + + public static File setOption(Endian endian) { + return File.setOption(Option.ENDIAN, endian); + } + + public File setOptions(AudioFormat audioFormat) { + setOption(Option.CHANNELS, audioFormat.getChannels()); + setOption(Option.RATE, String.format("%sk", String.valueOf(audioFormat.getSampleRate() / 1000f))); + AudioFormat.Encoding encoding = audioFormat.getEncoding(); + int bits = audioFormat.getSampleSizeInBits(); + if (encoding.equals(AudioFormat.Encoding.ALAW)) { + setOption(Format.AL); + setOption(Encoding.A_LAW); + } else if (encoding.equals(AudioFormat.Encoding.ULAW)) { + setOption(Format.UL); + setOption(Encoding.U_LAW); + } else if (encoding.equals(AudioFormat.Encoding.PCM_SIGNED)) { + setOption(Format.valueOf(String.format("S%d", bits))); + setOption(Encoding.SIGNED_INTEGER); + } else if (encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED)) { + setOption(Format.valueOf(String.format("U%d", bits))); + setOption(Encoding.UNSIGNED_INTEGER); + } + setOption(audioFormat.isBigEndian() ? Endian.BIG : Endian.LITTLE); + return instance; + } + + public static File setType(Type type) { + File.type = type; + return instance; + } + + public String build() { + String build = type.getCode(); + for (Entry entry : optionMap.entrySet()) { + String value = entry.getValue(); + if (value.equals("")) { + build = String.format("%s %s", entry.getKey(), build); + } else { + String option = String.format("%s %s", entry.getKey(), value); + build = String.format("%s %s", option, build); + } + } + reset(); + return build; + } + + public enum Option { + BITS ("--bits"), // (-b) + CHANNELS ("--channels"), // (-c) + ENCODING ("--encoding"), // (-e), |Encoding| + NO_GLOB ("--no-glob"), + RATE ("--rate"), // (-r) + FORMAT ("--type"), // (-t), |Format| + ENDIAN ("--endian"), // (-L, -B, -x), |Endian| + REVERSE_NIBBLES ("--reverse-nibbles"), // (-N) + REVERSE_BITS ("--reverse-bits"), // (-X) + /* Input only */ + IGNORE_LENGTH ("--ignore-length"), + VOLUME ("--volume"), // (-v) + /* Output only */ + ADD_COMMENT ("--add-comment"), + COMMENT ("--comment"), + COMMENT_FILE ("--comment-file"), + COMPRESSION ("--compression"); // -C + + protected String code; + + private Option(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + } + + public enum Encoding { + SIGNED_INTEGER ("signed-integer"), // PCM data stored as signed integers + UNSIGNED_INTEGER ("unsigned-integer"), // PCM data stored as unsigned integers + FLOATING_POINT ("floating-point"), // PCM data stored as single precision (32-bit) or double precision (64-bit) floating-point numbers + A_LAW ("a-lawW"), // International telephony standard for logarithmic encoding to 8 bits per sample (~13-bit PCM) + U_LAW ("u-law"), // North American telephony standard for logarithmic encoding to 8 bits per sample (~14-bit PCM) + MU_LAW ("mu-law"), // alias for u-law (~14-bit PCM) + OKI_ADPCM ("oki-adpcm"), // OKI (VOX, Dialogic or Intel) 4-bit ADPCM (~12-bit PCM) + IMA_ADPCM ("ima-adpcm"), // IMA (DVI) 4-bit ADPCM (~13-bit PCM) + MS_ADPCM ("ms-adpcm"), // Microsoft 4-bit ADPCM (~14-bit PCM) + GSM_FULL_RATE ("gsm-full-rate"); // Several audio formats used for digital wireless telephone calls + + protected String code; + + private Encoding(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + } + + public enum Format { + AIF, AIFC, AIFF, AIFFC, AL, AMB, AMR, ANY, ARL, AU, AVR, BIN, CAF, CDDA, CDR, CVS, CVSD, CVU, DAT, DVMS, EDU, F32, F64, FAP, FLAC, FSSD, GSM, GSRT, HCOM, HTK, IMA, IRCAM, LA, LPC, LPC10, LU, M3U, M4A, MAT, MAT4, MAT5, MAUD, MP2, MP3, MP4, NIST, OGG, PAF, PLS, PRC, PVF, RAW, S16, S24, S32, S8, SD2, SDS, SF, SLN, SMP, SND, SNDR, SNDT, SOU, SOX, SPH, TXW, U16, U24, U32, U8, UL, VMS, VOC, VORBIS, VOX, W64, WAV, WAVPCM, WV, WVE, XA, XI; + } + + public enum Endian { + LITTLE, BIG, SWAP; + } + + public enum Type { + STANDARD ("-"), // -t must be given + PIPE ("-p"), // (--sox-pipe) + DEVICE ("-d"), // (--default-device) + NULL ("-n"); // (--null) + + protected String code; + + private Type(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + } + } + + public class Effect { + public String build() { + return null; + } + } +} diff --git a/java/sound/src/main/java/sound/util/Tool.java b/java/sound/src/main/java/sound/util/Tool.java new file mode 100644 index 0000000..22d5076 --- /dev/null +++ b/java/sound/src/main/java/sound/util/Tool.java @@ -0,0 +1,140 @@ +package sound.util; + +import java.util.ArrayList; +import java.util.HashMap; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.Line; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.Port; +import javax.sound.sampled.Port.Info; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Tool { + protected static Logger logger = LoggerFactory.getLogger(Tool.class); + + protected static HashMap> targetMap; + protected static HashMap> sourceMap; + protected static ArrayList portList; + + protected static ArrayList targetList; + protected static ArrayList sourceList; + + static { + Tool tool = new Tool(); + + targetMap = new HashMap>(); + sourceMap = new HashMap>(); + targetList = new ArrayList(); + sourceList = new ArrayList(); + portList = new ArrayList(); + + for (Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) { + String name = mixerInfo.getName(); + Mixer mixer = AudioSystem.getMixer(mixerInfo); + + for (Line.Info lineInfo : mixer.getSourceLineInfo()) { + String lineClassName = lineInfo.getLineClass().getName(); + if (lineClassName.equals("javax.sound.sampled.SourceDataLine")) { + if (mixer.isLineSupported(lineInfo)) { + logger.debug(" " + name); + sourceMap.put(name, tool.new Device(mixer, lineInfo)); + } + } + } + for (Line.Info lineInfo : mixer.getTargetLineInfo()) { + String lineClassName = lineInfo.getLineClass().getName(); + if (lineClassName.equals("javax.sound.sampled.TargetDataLine")) { + if (mixer.isLineSupported(lineInfo)) { + logger.debug(" " + name); + targetMap.put(name, tool.new Device(mixer, lineInfo)); + } + } else if (lineClassName.equals("javax.sound.sampled.Port")) { + name = name.substring(5); + try { + Port port = (Port) mixer.getLine(lineInfo); + Port.Info portInfo = (Info) port.getLineInfo(); + if (!targetMap.containsKey(name) || portInfo.equals(Port.Info.LINE_OUT) || portInfo.equals(Port.Info.SPEAKER)) { + logger.debug(" " + name); + portList.add(name); + } + } catch (LineUnavailableException e) { + logger.error("", e); + } + } + } + } + } + + public static String[] getTargets() { + return targetMap.keySet().toArray(new String[0]); + } + + public static String[] getSources() { + return sourceMap.keySet().toArray(new String[0]); + } + + public static String[] getPorts() { + return portList.toArray(new String[0]); + } + + public static TargetDataLine getTargetDataLine(String name) throws LineUnavailableException { + if (targetMap.containsKey(name)) { + return targetMap.get(name).getLine(); + } else { + throw new LineUnavailableException(); + } + } + + public static TargetDataLine getTargetDataLine(String name, AudioFormat audioFormat) throws LineUnavailableException { + if (targetMap.containsKey(name)) { + return targetMap.get(name).getLine(audioFormat); + } else { + throw new LineUnavailableException(); + } + } + + public static SourceDataLine getSourceDataLine(String name) throws LineUnavailableException { + if (sourceMap.containsKey(name)) { + return sourceMap.get(name).getLine(); + } else { + throw new LineUnavailableException(); + } + } + + public static SourceDataLine getSourceDataLine(String name, AudioFormat audioFormat) throws LineUnavailableException { + if (sourceMap.containsKey(name)) { + return sourceMap.get(name).getLine(audioFormat); + } else { + throw new LineUnavailableException(); + } + } + + public class Device { + protected Mixer mixer; + protected Line.Info lineInfo; + + public Device(Mixer mixer, Line.Info lineInfo) { + this.mixer = mixer; + this.lineInfo = lineInfo; + } + + @SuppressWarnings("unchecked") + public T getLine() throws LineUnavailableException { + return (T) mixer.getLine(lineInfo); + } + + @SuppressWarnings("unchecked") + public T getLine(AudioFormat audioFormat) throws LineUnavailableException { + DataLine.Info dataLineInfo = new DataLine.Info(lineInfo.getLineClass(), audioFormat); + return (T) mixer.getLine(dataLineInfo); + } + } +} diff --git a/java/sound/src/main/java/sound/util/Utils.java b/java/sound/src/main/java/sound/util/Utils.java new file mode 100644 index 0000000..32100d8 --- /dev/null +++ b/java/sound/src/main/java/sound/util/Utils.java @@ -0,0 +1,39 @@ +package sound.util; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import javazoom.jl.decoder.JavaLayerException; +import javazoom.jl.player.Player; + +public class Utils { + public static final int BUFFER = 2048; // bytes + + public static void play(InputStream inputStream) { + try { + new Player(new BufferedInputStream(inputStream)).play(); + } catch (JavaLayerException e) { + e.printStackTrace(); + } + } + + public static void write(InputStream inputStream, File file) { + byte[] bytes = new byte[BUFFER]; + int read = 0; + try { + FileOutputStream fileOutputStream = new FileOutputStream(file); + while ((read = inputStream.read(bytes)) > 0) { + fileOutputStream.write(bytes, 0, read); + } + fileOutputStream.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/java/sound/src/main/java/test/SoundAudit.java b/java/sound/src/main/java/test/SoundAudit.java new file mode 100644 index 0000000..ee44f6a --- /dev/null +++ b/java/sound/src/main/java/test/SoundAudit.java @@ -0,0 +1,55 @@ +package test; + +import javax.sound.sampled.*; +public class SoundAudit { + public static void main(String[] args) { try { + System.out.println("OS: "+System.getProperty("os.name")+" "+ + System.getProperty("os.version")+"/"+ + System.getProperty("os.arch")+"\nJava: "+ + System.getProperty("java.version")+" ("+ + System.getProperty("java.vendor")+")\n"); + for (Mixer.Info thisMixerInfo : AudioSystem.getMixerInfo()) { + System.out.println("Mixer: "+thisMixerInfo.getDescription()+ + " ["+thisMixerInfo.getName()+"]"); + Mixer thisMixer = AudioSystem.getMixer(thisMixerInfo); + for (Line.Info thisLineInfo:thisMixer.getSourceLineInfo()) { + if (thisLineInfo.getLineClass().getName().equals( + "javax.sound.sampled.Port")) { + Line thisLine = thisMixer.getLine(thisLineInfo); + thisLine.open(); + System.out.println(" Source Port: " + +thisLineInfo.toString()); + for (Control thisControl : thisLine.getControls()) { + System.out.println(AnalyzeControl(thisControl));} + thisLine.close();}} + for (Line.Info thisLineInfo:thisMixer.getTargetLineInfo()) { + if (thisLineInfo.getLineClass().getName().equals( + "javax.sound.sampled.Port")) { + Line thisLine = thisMixer.getLine(thisLineInfo); + thisLine.open(); + System.out.println(" Target Port: " + +thisLineInfo.toString()); + for (Control thisControl : thisLine.getControls()) { + System.out.println(AnalyzeControl(thisControl));} + thisLine.close();}}} + } catch (Exception e) {e.printStackTrace();}} + public static String AnalyzeControl(Control thisControl) { + String type = thisControl.getType().toString(); + if (thisControl instanceof BooleanControl) { + return " Control: "+type+" (boolean)"; } + if (thisControl instanceof CompoundControl) { + System.out.println(" Control: "+type+ + " (compound - values below)"); + String toReturn = ""; + for (Control children: + ((CompoundControl)thisControl).getMemberControls()) { + toReturn+=" "+AnalyzeControl(children)+"\n";} + return toReturn.substring(0, toReturn.length()-1);} + if (thisControl instanceof EnumControl) { + return " Control:"+type+" (enum: "+thisControl.toString()+")";} + if (thisControl instanceof FloatControl) { + return " Control: "+type+" (float: from "+ + ((FloatControl) thisControl).getMinimum()+" to "+ + ((FloatControl) thisControl).getMaximum()+")";} + return " Control: unknown type";} +} diff --git a/java/sound/src/main/java/test/Test.java b/java/sound/src/main/java/test/Test.java new file mode 100644 index 0000000..067f2bf --- /dev/null +++ b/java/sound/src/main/java/test/Test.java @@ -0,0 +1,45 @@ +package test; + +import java.io.File; + +import javax.sound.sampled.AudioFormat; + +import sound.Consumer; +import sound.Producer; +import sound.Source; +import sound.consumer.Player; +import sound.consumer.Port; +import sound.consumer.Shoutcast; +import sound.consumer.Writer; +import sound.producer.Stream; +import sound.producer.Target; + +public class Test { + public static void main(String[] args) { + AudioFormat audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 48000f, 16, 2, 4, 48000f, true); + try { + //Producer p1 = new Target("Line-In (Creative SB X-Fi)"); + Producer p2 = new Target("Line 1 (Virtual Audio Cable)", audioFormat); + p2.start(); + Producer p3 = new Stream("http://ics2gss.omroep.nl:80/3fm-bb-mp3"); + Producer p4 = new Stream("http://sc7.mystreamserver.com:8004"); + + Consumer c1 = new Source("Java Sound Audio Engine"); + Consumer c2 = new Port("Speakers (Creative SB X-Fi)"); + Consumer c3 = new Shoutcast(); + Consumer c4 = new Player(); + Consumer c5 = new Writer(new File("stream.out")); + + //Utils.write(p3.getInputStream(), new File("stream.out")); + //Utils.play(p3.getInputStream()); + c3.start(p3); + + //while (true) { + //Thread.sleep(300000); + //c1.stop(); + //} + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/java/sound/src/main/java/test/lines/Main.java b/java/sound/src/main/java/test/lines/Main.java new file mode 100644 index 0000000..be6bbc2 --- /dev/null +++ b/java/sound/src/main/java/test/lines/Main.java @@ -0,0 +1,34 @@ +package test.lines; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Line; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; + +public class Main { + public static void main(String[] args) { + System.out.println(System.getProperty("javax.sound.sampled.SourceDataLine")); + + new AudioFormat(44100, 16, 2, true, false); + + for (Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) { + Mixer mixer = AudioSystem.getMixer(mixerInfo); + for (Line.Info lineInfo : mixer.getTargetLineInfo()) { + try { + Line line = mixer.getLine(lineInfo); + if (mixer.isLineSupported(lineInfo)) { + if (line instanceof TargetDataLine) { + new TargetLine(mixer, (TargetDataLine) line); + }/* else if (line instanceof SourceDataLine) { + new SourceLine(mixer, (SourceDataLine) line); + }*/ + } + } catch (LineUnavailableException e) {} + } + + } + } +} diff --git a/java/sound/src/main/java/test/lines/SourceLine.java b/java/sound/src/main/java/test/lines/SourceLine.java new file mode 100644 index 0000000..ede5969 --- /dev/null +++ b/java/sound/src/main/java/test/lines/SourceLine.java @@ -0,0 +1,19 @@ +package test.lines; + +import javax.sound.sampled.Mixer; +import javax.sound.sampled.SourceDataLine; + +public class SourceLine { + //private Mixer mixer; + private SourceDataLine line; + + public SourceLine(Mixer mixer, SourceDataLine line) { + //this.mixer = mixer; + this.line = line; + System.out.println("SOURCE " + mixer.getMixerInfo().getName() + " || " + line.getLineInfo()); + } + + public int write(byte[] bytes, int offset, int length) { + return line.write(bytes, offset, length); + } +} diff --git a/java/sound/src/main/java/test/lines/TargetLine.java b/java/sound/src/main/java/test/lines/TargetLine.java new file mode 100644 index 0000000..e1e7823 --- /dev/null +++ b/java/sound/src/main/java/test/lines/TargetLine.java @@ -0,0 +1,19 @@ +package test.lines; + +import javax.sound.sampled.Mixer; +import javax.sound.sampled.TargetDataLine; + +public class TargetLine { + //private Mixer mixer; + private TargetDataLine line; + + public TargetLine(Mixer mixer, TargetDataLine line) { + //this.mixer = mixer; + this.line = line; + System.out.println("TARGET " + mixer.getMixerInfo().getName() + " || " + line.getLineInfo()); + } + + public int read(byte[] bytes, int offset, int length) { + return line.read(bytes, offset, length); + } +} diff --git a/java/sound/stream.bat b/java/sound/stream.bat new file mode 100644 index 0000000..21afc51 --- /dev/null +++ b/java/sound/stream.bat @@ -0,0 +1 @@ +java -classpath bin udp.StreamClient 234.5.6.7 4567 \ No newline at end of file diff --git a/java/sound/stream.exe b/java/sound/stream.exe new file mode 100644 index 0000000..36bf506 Binary files /dev/null and b/java/sound/stream.exe differ diff --git a/java/sound/stream.jar b/java/sound/stream.jar new file mode 100644 index 0000000..1d8bbdc Binary files /dev/null and b/java/sound/stream.jar differ diff --git a/java/sound/txt/keuze.txt b/java/sound/txt/keuze.txt new file mode 100644 index 0000000..7e9581d --- /dev/null +++ b/java/sound/txt/keuze.txt @@ -0,0 +1,13 @@ +from pcm: + +-r -s [--unsigned] [--big-endian] + +to mp3: +--cbr -b + + +mp3 to pcm: +--decode + +always: + - - --quiet \ No newline at end of file diff --git a/java/sound/txt/mp3 b/java/sound/txt/mp3 new file mode 100644 index 0000000..daf87ab --- /dev/null +++ b/java/sound/txt/mp3 @@ -0,0 +1,1357 @@ +C:/Users/Rik/Music/Artists/+44/When Your Heart Stops Beating/+44 - 155.mp3 +C:/Users/Rik/Music/Artists/+44/When Your Heart Stops Beating/+44 - Baby Come On.mp3 +C:/Users/Rik/Music/Artists/+44/When Your Heart Stops Beating/+44 - Chapter 13.mp3 +C:/Users/Rik/Music/Artists/+44/When Your Heart Stops Beating/+44 - Cliff Diving.mp3 +C:/Users/Rik/Music/Artists/+44/When Your Heart Stops Beating/+44 - Interlude.mp3 +C:/Users/Rik/Music/Artists/+44/When Your Heart Stops Beating/+44 - Lillian.mp3 +C:/Users/Rik/Music/Artists/+44/When Your Heart Stops Beating/+44 - Little Death.mp3 +C:/Users/Rik/Music/Artists/+44/When Your Heart Stops Beating/+44 - Lycanthrope.mp3 +C:/Users/Rik/Music/Artists/+44/When Your Heart Stops Beating/+44 - Make You Smile.mp3 +C:/Users/Rik/Music/Artists/+44/When Your Heart Stops Beating/+44 - No, It Isn't.mp3 +C:/Users/Rik/Music/Artists/+44/When Your Heart Stops Beating/+44 - Weatherman.mp3 +C:/Users/Rik/Music/Artists/+44/When Your Heart Stops Beating/+44 - When Your Heart Stops Beating.mp3 +C:/Users/Rik/Music/Artists/10 Years Feeding/Feeding the Wolves/10 Years - Chasing the Rapture.mp3 +C:/Users/Rik/Music/Artists/10 Years Feeding/Feeding the Wolves/10 Years - Dead In the Water.mp3 +C:/Users/Rik/Music/Artists/10 Years Feeding/Feeding the Wolves/10 Years - Fade Into the Dream.mp3 +C:/Users/Rik/Music/Artists/10 Years Feeding/Feeding the Wolves/10 Years - Fix Me.mp3 +C:/Users/Rik/Music/Artists/10 Years Feeding/Feeding the Wolves/10 Years - Now Is the Time.mp3 +C:/Users/Rik/Music/Artists/10 Years Feeding/Feeding the Wolves/10 Years - One More Day.mp3 +C:/Users/Rik/Music/Artists/10 Years Feeding/Feeding the Wolves/10 Years - The Wicked Ones.mp3 +C:/Users/Rik/Music/Artists/10 Years Feeding/Feeding the Wolves/10 Years - Waking Up the Ghost.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/A Beautiful Lie/30 Seconds to Mars - A Beautiful Lie.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/A Beautiful Lie/30 Seconds to Mars - Attack.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/A Beautiful Lie/30 Seconds to Mars - Battle of One.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/A Beautiful Lie/30 Seconds to Mars - From Yesterday.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/A Beautiful Lie/30 Seconds to Mars - R-Evolve.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/A Beautiful Lie/30 Seconds to Mars - Savior.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/A Beautiful Lie/30 Seconds to Mars - The Fantasy.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/A Beautiful Lie/30 Seconds to Mars - Was It a Dream.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/This Is War/30 Seconds to Mars - A Call to Arms.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/This Is War/30 Seconds to Mars - Closer to the Edge.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/This Is War/30 Seconds to Mars - Equinox.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/This Is War/30 Seconds to Mars - Escape.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/This Is War/30 Seconds to Mars - Hurricane.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/This Is War/30 Seconds to Mars - Kings and Queens.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/This Is War/30 Seconds to Mars - Night of the Hunter (Flood Remix).mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/This Is War/30 Seconds to Mars - Night of the Hunter.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/This Is War/30 Seconds to Mars - Search & Destroy.mp3 +C:/Users/Rik/Music/Artists/30 Seconds To Mars/This Is War/30 Seconds to Mars - This Is War.mp3 +C:/Users/Rik/Music/Artists/All Time Low/Nothing Personal/All Time Low - A Party Song (The Walk of Shame).mp3 +C:/Users/Rik/Music/Artists/All Time Low/Nothing Personal/All Time Low - Break Your Little Heart.mp3 +C:/Users/Rik/Music/Artists/All Time Low/Nothing Personal/All Time Low - Damned If I Do Ya (Damned If I Don't).mp3 +C:/Users/Rik/Music/Artists/All Time Low/Nothing Personal/All Time Low - Hello Brooklyn.mp3 +C:/Users/Rik/Music/Artists/All Time Low/Nothing Personal/All Time Low - Keep the Change, You Filthy Animal.mp3 +C:/Users/Rik/Music/Artists/All Time Low/Nothing Personal/All Time Low - Lost In Stereo.mp3 +C:/Users/Rik/Music/Artists/All Time Low/Nothing Personal/All Time Low - Sick Little Games.mp3 +C:/Users/Rik/Music/Artists/All Time Low/Nothing Personal/All Time Low - Stella.mp3 +C:/Users/Rik/Music/Artists/All Time Low/Nothing Personal/All Time Low - Therapy.mp3 +C:/Users/Rik/Music/Artists/All Time Low/Nothing Personal/All Time Low - Too Much.mp3 +C:/Users/Rik/Music/Artists/All Time Low/Nothing Personal/All Time Low - Walls.mp3 +C:/Users/Rik/Music/Artists/All Time Low/Nothing Personal/All Time Low - Weightless.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Dark Is The Way, Light Is A Place/Anberlin - Art of War.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Dark Is The Way, Light Is A Place/Anberlin - Closer.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Dark Is The Way, Light Is A Place/Anberlin - Depraved.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Dark Is The Way, Light Is A Place/Anberlin - Down.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Dark Is The Way, Light Is A Place/Anberlin - Impossible.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Dark Is The Way, Light Is A Place/Anberlin - Pray Tell.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Dark Is The Way, Light Is A Place/Anberlin - Take Me (As You Found Me).mp3 +C:/Users/Rik/Music/Artists/Anberlin/Dark Is The Way, Light Is A Place/Anberlin - To the Wolves.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Dark Is The Way, Light Is A Place/Anberlin - We Owe This to Ourselves.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Dark Is The Way, Light Is A Place/Anberlin - You Belong Here.mp3 +C:/Users/Rik/Music/Artists/Angels & Airwaves/Love/Angels & Airwaves - Clever Love.mp3 +C:/Users/Rik/Music/Artists/Angels & Airwaves/Love/Angels & Airwaves - Epic Holiday.mp3 +C:/Users/Rik/Music/Artists/Angels & Airwaves/Love/Angels & Airwaves - Et Ducit Mundum Per Luce.mp3 +C:/Users/Rik/Music/Artists/Angels & Airwaves/Love/Angels & Airwaves - Hallucinations.mp3 +C:/Users/Rik/Music/Artists/Angels & Airwaves/Love/Angels & Airwaves - Letters to God, Part Ii.mp3 +C:/Users/Rik/Music/Artists/Angels & Airwaves/Love/Angels & Airwaves - Shove.mp3 +C:/Users/Rik/Music/Artists/Angels & Airwaves/Love/Angels & Airwaves - Some Origins of Fire.mp3 +C:/Users/Rik/Music/Artists/Angels & Airwaves/Love/Angels & Airwaves - Soul Survivor (...2012).mp3 +C:/Users/Rik/Music/Artists/Angels & Airwaves/Love/Angels & Airwaves - The Flight of Apollo.mp3 +C:/Users/Rik/Music/Artists/Angels & Airwaves/Love/Angels & Airwaves - The Moon-Atomic (...Fragments and Fictions).mp3 +C:/Users/Rik/Music/Artists/Angels & Airwaves/Love/Angels & Airwaves - Young London.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/The Suburbs/Arcade Fire - City With No Children.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/The Suburbs/Arcade Fire - Empty Room.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/The Suburbs/Arcade Fire - Half Light Ii (No Celebration).mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/The Suburbs/Arcade Fire - Modern Man.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/The Suburbs/Arcade Fire - Month of May.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/The Suburbs/Arcade Fire - Suburban War.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - Adam's Song.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - All the Small Things.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - Always.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - Another Girl Another Planet.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - Carousel.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - Dammit.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - Down.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - Feelin' This.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - First Date.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - Josie.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - M&m's.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - Man Overboard (Live).mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - Miss You.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - Not Now.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - Rock Show.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - Stay Together For the Kids.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Greatest Hits/Blink-182 - What's My Age Again.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Coldplay - Clocks.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Coldplay - In My Place.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Coldplay - Life In Technicolor Ii.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Coldplay - Speed of Sound.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Coldplay - Talk.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Viva la Vida or Death and All His Friends/Coldplay - Life In Technicolor.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Viva la Vida or Death and All His Friends/Coldplay - Lost!.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Viva la Vida or Death and All His Friends/Coldplay - Lovers In Japan Reign of Love.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Viva la Vida or Death and All His Friends/Coldplay - Viva La Vida.mp3 +C:/Users/Rik/Music/Artists/Counting Crows/Counting Crows - Accidentally In Love.mp3 +C:/Users/Rik/Music/Artists/Counting Crows/Films About Ghosts - The Best Of/Counting Crows - American Girls.mp3 +C:/Users/Rik/Music/Artists/Counting Crows/Films About Ghosts - The Best Of/Counting Crows - Angels of the Silences.mp3 +C:/Users/Rik/Music/Artists/Counting Crows/Films About Ghosts - The Best Of/Counting Crows - Big Yellow Taxi.mp3 +C:/Users/Rik/Music/Artists/Counting Crows/Films About Ghosts - The Best Of/Counting Crows - Einstein On the Beach (For An Eggman).mp3 +C:/Users/Rik/Music/Artists/Counting Crows/Films About Ghosts - The Best Of/Counting Crows - Friend of the Devil.mp3 +C:/Users/Rik/Music/Artists/Counting Crows/Films About Ghosts - The Best Of/Counting Crows - Hanginaround.mp3 +C:/Users/Rik/Music/Artists/Counting Crows/Films About Ghosts - The Best Of/Counting Crows - Mr. Jones.mp3 +C:/Users/Rik/Music/Artists/Counting Crows/Films About Ghosts - The Best Of/Counting Crows - Mrs. Potter's Lullaby.mp3 +C:/Users/Rik/Music/Artists/Counting Crows/Films About Ghosts - The Best Of/Counting Crows - Omaha.mp3 +C:/Users/Rik/Music/Artists/Counting Crows/Films About Ghosts - The Best Of/Counting Crows - Rain King.mp3 +C:/Users/Rik/Music/Artists/Counting Crows/Films About Ghosts - The Best Of/Counting Crows - Recovering the Satellites.mp3 +C:/Users/Rik/Music/Artists/Counting Crows/Films About Ghosts - The Best Of/Counting Crows - She Don't Want Nobody Near.mp3 +C:/Users/Rik/Music/Artists/Destine/Lightspeed/Destine - Am I So Blind.mp3 +C:/Users/Rik/Music/Artists/Destine/Lightspeed/Destine - Burn.mp3 +C:/Users/Rik/Music/Artists/Destine/Lightspeed/Destine - California Summer.mp3 +C:/Users/Rik/Music/Artists/Destine/Lightspeed/Destine - Everything In Me.mp3 +C:/Users/Rik/Music/Artists/Destine/Lightspeed/Destine - Forget About Me.mp3 +C:/Users/Rik/Music/Artists/Destine/Lightspeed/Destine - In the End.mp3 +C:/Users/Rik/Music/Artists/Destine/Lightspeed/Destine - In Your Arms.mp3 +C:/Users/Rik/Music/Artists/Destine/Lightspeed/Destine - Sinking Sand.mp3 +C:/Users/Rik/Music/Artists/Destine/Lightspeed/Destine - Spiders.mp3 +C:/Users/Rik/Music/Artists/Destine/Lightspeed/Destine - Stars.mp3 +C:/Users/Rik/Music/Artists/Destine/Lightspeed/Destine - Wake Me.mp3 +C:/Users/Rik/Music/Artists/Destine/Lightspeed/Destine - Where Are You Now.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect - Hungry For Love.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect - She.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect/Di-Rect - A Good Thing.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect/Di-Rect - A Whole New Era.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect/Di-Rect - Break Us In Two.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect/Di-Rect - Bring Down Tomorrow.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect/Di-Rect - Don't Look Back.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect/Di-Rect - I Juct Can't Stand.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect/Di-Rect - It Feels.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect/Di-Rect - Johny.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect/Di-Rect - Lucky.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect/Di-Rect - One Step Closer.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect/Di-Rect - Over and Over.mp3 +C:/Users/Rik/Music/Artists/Di-Rect/Di-Rect/Di-Rect - Someday.mp3 +C:/Users/Rik/Music/Artists/Dropout Year/Best Friends For Never/Dropout Year - A Coming of Age Story.mp3 +C:/Users/Rik/Music/Artists/Dropout Year/Best Friends For Never/Dropout Year - As You Wish.mp3 +C:/Users/Rik/Music/Artists/Dropout Year/Best Friends For Never/Dropout Year - Best Friends For Never.mp3 +C:/Users/Rik/Music/Artists/Dropout Year/Best Friends For Never/Dropout Year - Biggest Fan.mp3 +C:/Users/Rik/Music/Artists/Dropout Year/Best Friends For Never/Dropout Year - Confetti.mp3 +C:/Users/Rik/Music/Artists/Dropout Year/Best Friends For Never/Dropout Year - From Across the Room.mp3 +C:/Users/Rik/Music/Artists/Dropout Year/Best Friends For Never/Dropout Year - It Wasn't Over, It Still Isn't Over.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Folie A Deux/Fall Out Boy - (Coffee's For Closers).mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Folie A Deux/Fall Out Boy - 20 Dollar Nose Bleed.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Folie A Deux/Fall Out Boy - 27.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Folie A Deux/Fall Out Boy - America's Suitehearts.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Folie A Deux/Fall Out Boy - Disloyal Order of Water Buffaloes.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Folie A Deux/Fall Out Boy - Headfirst Slide Into Coopestown On a Bad Bet.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Folie A Deux/Fall Out Boy - I Don't Care.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Folie A Deux/Fall Out Boy - She's My Winona.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Folie A Deux/Fall Out Boy - Tiffany Blews.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Folie A Deux/Fall Out Boy - West Coast Smoker.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Folie A Deux/Fall Out Boy - What a Catch, Donnie.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - All My Life.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - Best of You.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - Big Me.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - Breakout.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - Everlong.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - Learn to Fly.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - Long Road to Ruin.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - Monkey Wrench.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - My Hero.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - The Pretender.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - This Is a Call.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - Times Like These.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - Wheels.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - Word Forward.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Wasting Light/Foo Fighters - A Matter of Time.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Wasting Light/Foo Fighters - Arlandria.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Wasting Light/Foo Fighters - Back & Forth.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Wasting Light/Foo Fighters - Bridge Burning.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Wasting Light/Foo Fighters - Dear Rosemary.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Wasting Light/Foo Fighters - Miss the Misery.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Wasting Light/Foo Fighters - Rope.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Wasting Light/Foo Fighters - These Days.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Wasting Light/Foo Fighters - Walk.mp3 +C:/Users/Rik/Music/Artists/Go Back To The Zoo/Benny Blisto/Go Back to the Zoo - Beam Me Up.mp3 +C:/Users/Rik/Music/Artists/Go Back To The Zoo/Benny Blisto/Go Back to the Zoo - Electric.mp3 +C:/Users/Rik/Music/Artists/Go Back To The Zoo/Benny Blisto/Go Back to the Zoo - Fuck You.mp3 +C:/Users/Rik/Music/Artists/Go Back To The Zoo/Benny Blisto/Go Back to the Zoo - Hey Dj.mp3 +C:/Users/Rik/Music/Artists/Go Back To The Zoo/Benny Blisto/Go Back to the Zoo - I Lov It.mp3 +C:/Users/Rik/Music/Artists/Go Back To The Zoo/Benny Blisto/Go Back to the Zoo - I'm the Night (See You Later).mp3 +C:/Users/Rik/Music/Artists/Go Back To The Zoo/Benny Blisto/Go Back to the Zoo - Nicer.mp3 +C:/Users/Rik/Music/Artists/Go Back To The Zoo/Benny Blisto/Go Back to the Zoo - Oh No (We Stayed).mp3 +C:/Users/Rik/Music/Artists/Go Back To The Zoo/Benny Blisto/Go Back to the Zoo - Sweet World.mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - 1979.mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - Alive.mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - Cardiology.mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - Counting the Days.mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - Harlow's Song (Can't Dream Without You).mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - Interlude (The Fifth Chamber).mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - Introduction to Cardiology.mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - Last Night.mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - Let the Music Play.mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - Like It's Her Birthday.mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - Right Where I Belong.mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - Sex On the Radio.mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - Silver Screen Romance.mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - Standing Ovation.mp3 +C:/Users/Rik/Music/Artists/Good Charlotte/Cardiology/Good Charlotte - There She Goes.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - 21 Guns.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - 21st Century Breakdown.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - American Eulogy.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - Before the Lobotomy.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - Christian's Inferno.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - East Jesus Nowhere.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - Horseshoes and Handgrenades.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - Know Your Enemy.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - Last Night On Earth.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - Last of the American Girls.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - Murder City.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - Peacemaker.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - Restless Heart Syndrome.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - See the Light.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - The Static Age.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - Viva La Gloria (Little Girl).mp3 +C:/Users/Rik/Music/Artists/Green Day/American Idiot/Green Day - American Idiot.mp3 +C:/Users/Rik/Music/Artists/Green Day/American Idiot/Green Day - Are We the Waiting.mp3 +C:/Users/Rik/Music/Artists/Green Day/American Idiot/Green Day - Boulevard of Broken Dreams.mp3 +C:/Users/Rik/Music/Artists/Green Day/American Idiot/Green Day - Extraordinary Girl.mp3 +C:/Users/Rik/Music/Artists/Green Day/American Idiot/Green Day - Give Me Novacaine.mp3 +C:/Users/Rik/Music/Artists/Green Day/American Idiot/Green Day - Holiday.mp3 +C:/Users/Rik/Music/Artists/Green Day/American Idiot/Green Day - Homecoming.mp3 +C:/Users/Rik/Music/Artists/Green Day/American Idiot/Green Day - Jesus of Suburbia.mp3 +C:/Users/Rik/Music/Artists/Green Day/American Idiot/Green Day - Letterbomb.mp3 +C:/Users/Rik/Music/Artists/Green Day/American Idiot/Green Day - She's a Rebel.mp3 +C:/Users/Rik/Music/Artists/Green Day/American Idiot/Green Day - St. Jimmy.mp3 +C:/Users/Rik/Music/Artists/Green Day/American Idiot/Green Day - Wake Me Up When September Ends.mp3 +C:/Users/Rik/Music/Artists/Green Day/American Idiot/Green Day - Whatsername.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - All the Time.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Armatage Shanks.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Bascet Case.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Brat.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Burnout.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Chump.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Church On Sunday.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Coming Clean.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Desensitized.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Emenius Sleepus.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Fashion Victim.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Geek Stink Breath.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Good Riddance (Time of Your Life).mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - In the End.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - J.A.R. (Jason Andrew Relva).mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Jaded.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Maria.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Nice Guys Finish Last.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Poprocks & Coke.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Redundant.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Scumbag.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - She.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Stuck With Me.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Suffocate.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - The Grouch.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - The Saints Are Coming.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Waiting.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Walking Alone.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Walking Contradiction.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Warning.mp3 +C:/Users/Rik/Music/Artists/Green Day/Greatest Hits/Green Day - Welcome to Paradise.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Off With Their Heads/Kaiser Chiefs - Addicted to Drugs.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Off With Their Heads/Kaiser Chiefs - Always Happens Like That.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Off With Their Heads/Kaiser Chiefs - Can't Say What I Mean.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Off With Their Heads/Kaiser Chiefs - Good Days Bad Days.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Off With Their Heads/Kaiser Chiefs - Half the Truth.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Off With Their Heads/Kaiser Chiefs - Like It Too Much.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Off With Their Heads/Kaiser Chiefs - Never Miss a Beat.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Off With Their Heads/Kaiser Chiefs - Spanish Metal.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Off With Their Heads/Kaiser Chiefs - Tomato In the Rain.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Off With Their Heads/Kaiser Chiefs - You Want History.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Yours Truly, Angry Mob/Kaiser Chiefs - Boxing Champ.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Yours Truly, Angry Mob/Kaiser Chiefs - Everything Is Average Nowadays.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Yours Truly, Angry Mob/Kaiser Chiefs - Heat Dies Down.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Yours Truly, Angry Mob/Kaiser Chiefs - Highroyds.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Yours Truly, Angry Mob/Kaiser Chiefs - I Can Do Without You.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Yours Truly, Angry Mob/Kaiser Chiefs - Learnt My Lesson Well.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Yours Truly, Angry Mob/Kaiser Chiefs - Love's Not a Competition (But I'm Winning).mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Yours Truly, Angry Mob/Kaiser Chiefs - My Kind of Guy.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Yours Truly, Angry Mob/Kaiser Chiefs - Retirement.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Yours Truly, Angry Mob/Kaiser Chiefs - Ruby.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Yours Truly, Angry Mob/Kaiser Chiefs - Thank You Very Much.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Yours Truly, Angry Mob/Kaiser Chiefs - The Angry Mob.mp3 +C:/Users/Rik/Music/Artists/Kaiser Chiefs/Yours Truly, Angry Mob/Kaiser Chiefs - Try Your Best.mp3 +C:/Users/Rik/Music/Artists/Keane/Keane - Everybody's Changing.mp3 +C:/Users/Rik/Music/Artists/Keane/Keane - Is It Any Wonder.mp3 +C:/Users/Rik/Music/Artists/Keane/Keane - Somewhere Only We Know.mp3 +C:/Users/Rik/Music/Artists/Keane/Keane - This Is the Last Time.mp3 +C:/Users/Rik/Music/Artists/Keane/Perfect Symmetry/Keane - Again & Again.mp3 +C:/Users/Rik/Music/Artists/Keane/Perfect Symmetry/Keane - Better Than This.mp3 +C:/Users/Rik/Music/Artists/Keane/Perfect Symmetry/Keane - Black Burning Heart.mp3 +C:/Users/Rik/Music/Artists/Keane/Perfect Symmetry/Keane - Lovers Are Losing.mp3 +C:/Users/Rik/Music/Artists/Keane/Perfect Symmetry/Keane - Perfect Symmetry.mp3 +C:/Users/Rik/Music/Artists/Keane/Perfect Symmetry/Keane - Playing Along.mp3 +C:/Users/Rik/Music/Artists/Keane/Perfect Symmetry/Keane - Pretend That You're Alone.mp3 +C:/Users/Rik/Music/Artists/Keane/Perfect Symmetry/Keane - Spiralling.mp3 +C:/Users/Rik/Music/Artists/Keane/Perfect Symmetry/Keane - You Don't See Me.mp3 +C:/Users/Rik/Music/Artists/Kensington/Borders/Kensington - All That I Know.mp3 +C:/Users/Rik/Music/Artists/Kensington/Borders/Kensington - Franklin Exits.mp3 +C:/Users/Rik/Music/Artists/Kensington/Borders/Kensington - I Was Too Scared.mp3 +C:/Users/Rik/Music/Artists/Kensington/Borders/Kensington - Not As Bright.mp3 +C:/Users/Rik/Music/Artists/Kensington/Borders/Kensington - So Am I.mp3 +C:/Users/Rik/Music/Artists/Kensington/Borders/Kensington - The Heart of It.mp3 +C:/Users/Rik/Music/Artists/Kensington/Borders/Kensington - Thieves and Murderers.mp3 +C:/Users/Rik/Music/Artists/Kensington/Borders/Kensington - Waiting For a Sign.mp3 +C:/Users/Rik/Music/Artists/Kensington/Borders/Kensington - What's Gotten Into Us.mp3 +C:/Users/Rik/Music/Artists/Kensington/Borders/Kensington - When It All Falls Down.mp3 +C:/Users/Rik/Music/Artists/Kensington/Borders/Kensington - Youth.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Come Around Sundown/Kings of Leon - Back Down South.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Come Around Sundown/Kings of Leon - Beach Side.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Come Around Sundown/Kings of Leon - Birthday.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Come Around Sundown/Kings of Leon - Mary.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Come Around Sundown/Kings of Leon - Mi Amigo.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Come Around Sundown/Kings of Leon - No Money.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Come Around Sundown/Kings of Leon - Pickup Truck.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Come Around Sundown/Kings of Leon - Pony Up.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Come Around Sundown/Kings of Leon - Pyro.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Come Around Sundown/Kings of Leon - Radioactive.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Come Around Sundown/Kings of Leon - The End.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Come Around Sundown/Kings of Leon - The Face.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Come Around Sundown/Kings of Leon - The Immortals.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Only By The Night/Kings of Leon - Be Somebody.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Only By The Night/Kings of Leon - Closer.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Only By The Night/Kings of Leon - Crawl.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Only By The Night/Kings of Leon - I Want You.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Only By The Night/Kings of Leon - Manhattan.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Only By The Night/Kings of Leon - Notion.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Only By The Night/Kings of Leon - Sex On Fire.mp3 +C:/Users/Rik/Music/Artists/Kings of Leon/Only By The Night/Kings of Leon - Use Somebody.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Smoke & Mirrors/Lifehouse - All In.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Smoke & Mirrors/Lifehouse - All That I'm Asking For.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Smoke & Mirrors/Lifehouse - By Your Side.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Smoke & Mirrors/Lifehouse - Crash and Burn.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Smoke & Mirrors/Lifehouse - Falling In.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Smoke & Mirrors/Lifehouse - From Where You Are.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Smoke & Mirrors/Lifehouse - Had Enough.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Smoke & Mirrors/Lifehouse - Halfway Gone.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Smoke & Mirrors/Lifehouse - In Your Skin.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Smoke & Mirrors/Lifehouse - It Is What It Is.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Smoke & Mirrors/Lifehouse - Smoke & Mirrors.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Smoke & Mirrors/Lifehouse - Wrecking Ball.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Who We Are/Lifehouse - Bridges.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Who We Are/Lifehouse - Disarray.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Who We Are/Lifehouse - Easier to Be.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Who We Are/Lifehouse - First Time.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Who We Are/Lifehouse - Learn You Inside Out.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Who We Are/Lifehouse - Make Me Over.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Who We Are/Lifehouse - Mesmerized.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Who We Are/Lifehouse - Storm.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Who We Are/Lifehouse - Whatever It Takes.mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Who We Are/Lifehouse - Who We Are.mp3 +C:/Users/Rik/Music/Artists/Linking Park/Hybrid Theory/Linkin Park - A Place For My Head.mp3 +C:/Users/Rik/Music/Artists/Linking Park/Hybrid Theory/Linkin Park - Crawling.mp3 +C:/Users/Rik/Music/Artists/Linking Park/Hybrid Theory/Linkin Park - Forgotten.mp3 +C:/Users/Rik/Music/Artists/Linking Park/Hybrid Theory/Linkin Park - In the End.mp3 +C:/Users/Rik/Music/Artists/Linking Park/Hybrid Theory/Linkin Park - One Step Closer.mp3 +C:/Users/Rik/Music/Artists/Linking Park/Hybrid Theory/Linkin Park - Papercut.mp3 +C:/Users/Rik/Music/Artists/Linking Park/Hybrid Theory/Linkin Park - Points of Authority.mp3 +C:/Users/Rik/Music/Artists/Linking Park/Hybrid Theory/Linkin Park - Pushing Me Away.mp3 +C:/Users/Rik/Music/Artists/Linking Park/Hybrid Theory/Linkin Park - Runaway.mp3 +C:/Users/Rik/Music/Artists/Linking Park/Hybrid Theory/Linkin Park - With You.mp3 +C:/Users/Rik/Music/Artists/Lostprophets/Liberation Transmission/Lostprophets - 4am Forever.mp3 +C:/Users/Rik/Music/Artists/Lostprophets/Liberation Transmission/Lostprophets - A Town Called Hypocrisy.mp3 +C:/Users/Rik/Music/Artists/Lostprophets/Liberation Transmission/Lostprophets - Always All Ways (Apologies, Glances and Messed Up Chances).mp3 +C:/Users/Rik/Music/Artists/Lostprophets/Liberation Transmission/Lostprophets - Broken Hearts, Torn Up Letters and the Story of a Lonely Girl.mp3 +C:/Users/Rik/Music/Artists/Lostprophets/Liberation Transmission/Lostprophets - Can't Catch Tomorrow (Good Shoes Won't Save You This Time).mp3 +C:/Users/Rik/Music/Artists/Lostprophets/Liberation Transmission/Lostprophets - Can't Stop, Gotta Date With Hate.mp3 +C:/Users/Rik/Music/Artists/Lostprophets/Liberation Transmission/Lostprophets - Everybody's Screaming !!!.mp3 +C:/Users/Rik/Music/Artists/Lostprophets/Liberation Transmission/Lostprophets - Everyday Combat.mp3 +C:/Users/Rik/Music/Artists/Lostprophets/Liberation Transmission/Lostprophets - For All These Times Son, For All These Times.mp3 +C:/Users/Rik/Music/Artists/Lostprophets/Liberation Transmission/Lostprophets - Heaven For the Weather, Hell For the Company.mp3 +C:/Users/Rik/Music/Artists/Lostprophets/Liberation Transmission/Lostprophets - Rooftops (A Liberation Broadcast).mp3 +C:/Users/Rik/Music/Artists/Lostprophets/Liberation Transmission/Lostprophets - The New Transmission.mp3 +C:/Users/Rik/Music/Artists/Matchbook Romance/Voices/Matchbook Romance - Goody, Like Two Shoes.mp3 +C:/Users/Rik/Music/Artists/Matchbook Romance/Voices/Matchbook Romance - Monsters.mp3 +C:/Users/Rik/Music/Artists/Matchbook Romance/Voices/Matchbook Romance - My Mannequin Can Dance.mp3 +C:/Users/Rik/Music/Artists/Matchbook Romance/Voices/Matchbook Romance - Portrait.mp3 +C:/Users/Rik/Music/Artists/Matchbook Romance/Voices/Matchbook Romance - Singing Bridges (We All Fall).mp3 +C:/Users/Rik/Music/Artists/Matchbook Romance/Voices/Matchbook Romance - Surrender.mp3 +C:/Users/Rik/Music/Artists/Matchbook Romance/Voices/Matchbook Romance - What a Sight.mp3 +C:/Users/Rik/Music/Artists/Neon Trees/Habits/Neon Trees - 1983.mp3 +C:/Users/Rik/Music/Artists/Neon Trees/Habits/Neon Trees - Animal.mp3 +C:/Users/Rik/Music/Artists/Neon Trees/Habits/Neon Trees - In the Next Room.mp3 +C:/Users/Rik/Music/Artists/Neon Trees/Habits/Neon Trees - Sins of My Youth.mp3 +C:/Users/Rik/Music/Artists/Neon Trees/Habits/Neon Trees - Your Surrender.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Dark Horse/Nickelback - Gotta Be Somebody.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Dark Horse/Nickelback - I'd Come For You.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Dark Horse/Nickelback - If Today Was Your Last Day.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Dark Horse/Nickelback - Just to Get High.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Dark Horse/Nickelback - Never Gonna Be Alone.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Dark Horse/Nickelback - This Afternoon.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Nickelback - How You Remind Me.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Nickelback - Photograph.mp3 +C:/Users/Rik/Music/Artists/OneRepublic/Waking Up/Onerepublic - All the Right Moves.mp3 +C:/Users/Rik/Music/Artists/OneRepublic/Waking Up/Onerepublic - Fear.mp3 +C:/Users/Rik/Music/Artists/OneRepublic/Waking Up/Onerepublic - Good Life.mp3 +C:/Users/Rik/Music/Artists/OneRepublic/Waking Up/Onerepublic - Secrets.mp3 +C:/Users/Rik/Music/Artists/Plain White T's/All That We Needed/Plain White T's - All That We Needed.mp3 +C:/Users/Rik/Music/Artists/Plain White T's/All That We Needed/Plain White T's - Anything.mp3 +C:/Users/Rik/Music/Artists/Plain White T's/All That We Needed/Plain White T's - Breakdown.mp3 +C:/Users/Rik/Music/Artists/Plain White T's/All That We Needed/Plain White T's - Faster.mp3 +C:/Users/Rik/Music/Artists/Plain White T's/All That We Needed/Plain White T's - Last Call.mp3 +C:/Users/Rik/Music/Artists/Plain White T's/All That We Needed/Plain White T's - Lazy Day Afternoon.mp3 +C:/Users/Rik/Music/Artists/Plain White T's/All That We Needed/Plain White T's - My Only One.mp3 +C:/Users/Rik/Music/Artists/Plain White T's/All That We Needed/Plain White T's - Revenge.mp3 +C:/Users/Rik/Music/Artists/Plain White T's/All That We Needed/Plain White T's - Sad Story.mp3 +C:/Users/Rik/Music/Artists/Plain White T's/All That We Needed/Plain White T's - Sing My Best.mp3 +C:/Users/Rik/Music/Artists/Plain White T's/All That We Needed/Plain White T's - Take Me Away.mp3 +C:/Users/Rik/Music/Artists/Plain White T's/All That We Needed/Plain White T's - What More Do You Want.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - Breaking the Girl.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - By the Way.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - Californication.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - Fortune Faded.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - Give It Away.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - Higher Ground.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - My Friends.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - Otherside.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - Parallel Universe.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - Save the Population.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - Scar Tissue.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - Soul to Squeeze.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - Under the Bridge.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Greatest Hits/Red Hot Chili Peppers - Universally Speaking.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Animal Bar.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Charlie.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - C'mon Girl.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Dani California.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Death of a Martian.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Desecration Smile.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Especially In Michigan.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Hard to Concentrate.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Hey.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - If.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Make You Feel Better.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - She Looks to Me.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - She's Only 18.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Slow Cheetah.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Snow (Hey Oh).mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - So Much I.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Stadium Arcadium.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Storm In a Teacup.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Strip My Mind.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Tell Me Baby.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Torture Me.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Turn It Again.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Warlocks.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - We Believe.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/Stadium Arcadium/Red Hot Chili Peppers - Wet Sand.mp3 +C:/Users/Rik/Music/Artists/Rooney/Calling The World/Rooney - All In Your Head.mp3 +C:/Users/Rik/Music/Artists/Rooney/Calling The World/Rooney - Are You Afraid.mp3 +C:/Users/Rik/Music/Artists/Rooney/Calling The World/Rooney - Believe In Me.mp3 +C:/Users/Rik/Music/Artists/Rooney/Calling The World/Rooney - Calling the World.mp3 +C:/Users/Rik/Music/Artists/Rooney/Calling The World/Rooney - Don't Come Around Again.mp3 +C:/Users/Rik/Music/Artists/Rooney/Calling The World/Rooney - I Should've Been After You.mp3 +C:/Users/Rik/Music/Artists/Rooney/Calling The World/Rooney - Love Me Or Leave Me.mp3 +C:/Users/Rik/Music/Artists/Rooney/Calling The World/Rooney - Paralyzed.mp3 +C:/Users/Rik/Music/Artists/Rooney/Calling The World/Rooney - What For.mp3 +C:/Users/Rik/Music/Artists/Savage Garden/Savage Garden/Savage Garden - A Thousand Words.mp3 +C:/Users/Rik/Music/Artists/Savage Garden/Savage Garden/Savage Garden - Break Me Shake Me.mp3 +C:/Users/Rik/Music/Artists/Savage Garden/Savage Garden/Savage Garden - Carry On Dancing.mp3 +C:/Users/Rik/Music/Artists/Savage Garden/Savage Garden/Savage Garden - I Want You.mp3 +C:/Users/Rik/Music/Artists/Savage Garden/Savage Garden/Savage Garden - To the Moon and Back.mp3 +C:/Users/Rik/Music/Artists/Savage Garden/Savage Garden/Savage Garden - Truly Madly Deeply.mp3 +C:/Users/Rik/Music/Artists/Savage Garden/Savage Garden/Savage Garden - Violet.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Simple Plan/Simple Plan - Generation.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Simple Plan/Simple Plan - I Can Wait Forever.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Simple Plan/Simple Plan - No Love.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Simple Plan/Simple Plan - Running Out of Time.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Simple Plan/Simple Plan - Save You.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Simple Plan/Simple Plan - Take My Hand.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Simple Plan/Simple Plan - The End.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Simple Plan/Simple Plan - Time to Say Goodbye.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Simple Plan/Simple Plan - What If.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Simple Plan/Simple Plan - When I'm Gone (Acoustic).mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Simple Plan/Simple Plan - When I'm Gone.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Simple Plan/Simple Plan - Your Love Is a Lie.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/A Hundred Million Suns/Snow Patrol - Crack the Shutters.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/A Hundred Million Suns/Snow Patrol - Disaster Button.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/A Hundred Million Suns/Snow Patrol - Engines.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/A Hundred Million Suns/Snow Patrol - If There's a Rocket Tie Me to It.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/A Hundred Million Suns/Snow Patrol - Please Just Take These Photos From My Hands.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/A Hundred Million Suns/Snow Patrol - Take Back the City.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/Eyes Open/Snow Patrol - Chasing Cars.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/Eyes Open/Snow Patrol - Hands Open .mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/Eyes Open/Snow Patrol - Headlights On Dark Roads.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/Eyes Open/Snow Patrol - In My Arms.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/Eyes Open/Snow Patrol - It's Beginning to Get to Me.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/Eyes Open/Snow Patrol - Open Your Eyes .mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/Eyes Open/Snow Patrol - Shut Your Eyes .mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/Eyes Open/Snow Patrol - Warmer Climate.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/Eyes Open/Snow Patrol - You're All I Have.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/Snow Patrol - Chocolate.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/Snow Patrol - Just Say Yes.mp3 +C:/Users/Rik/Music/Artists/Snow Patrol/Snow Patrol - Run.mp3 +C:/Users/Rik/Music/Artists/So They Say/Antidote for Irony/So They Say - Anxiety Is Setting In.mp3 +C:/Users/Rik/Music/Artists/So They Say/Antidote for Irony/So They Say - Good-Bye.mp3 +C:/Users/Rik/Music/Artists/So They Say/Antidote for Irony/So They Say - In Essence We Are Falling.mp3 +C:/Users/Rik/Music/Artists/So They Say/Antidote for Irony/So They Say - In Loving Memory Of....mp3 +C:/Users/Rik/Music/Artists/So They Say/Antidote for Irony/So They Say - Over Exposed Photo.mp3 +C:/Users/Rik/Music/Artists/So They Say/Antidote for Irony/So They Say - Talking In Circles.mp3 +C:/Users/Rik/Music/Artists/So They Say/Antidote for Irony/So They Say - The Burden.mp3 +C:/Users/Rik/Music/Artists/So They Say/Antidote for Irony/So They Say - You Asked, Where Are You Now.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Anna.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Dying.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Hate Not Gone.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Hesitate.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Home Again.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Imperfect.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Let's Be Honest.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Miracles.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Mission Statement.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Nylon 66.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Pieces.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Say You'll Haunt Me.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - The Bitter End.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Threadbare.mp3 +C:/Users/Rik/Music/Artists/Stone Sour/Audio Secrecy/Stone Sour - Unfinished.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Baby You Don't Wanna Know.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Back Where I Belong.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Blood In My Eyes.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Crash.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Exit Song.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Happiness Machine.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Holy Image of Lies.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Jessica Kill.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Reason to Believe (Acoustic).mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Reason to Believe.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Screaming Bloody Murder.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Sick of Everyone.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Skumfuk.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - Time For You to Go.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - What Am I to Say.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Underclass Hero/Sum 41 - Best of Me.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Underclass Hero/Sum 41 - Confusion and Frustration In Modern Times.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Underclass Hero/Sum 41 - Count Your Last Blessings.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Underclass Hero/Sum 41 - Dear Father.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Underclass Hero/Sum 41 - King of Contradiction.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Underclass Hero/Sum 41 - March of the Dogs.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Underclass Hero/Sum 41 - Pull the Curtain.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Underclass Hero/Sum 41 - So Long Goodbye.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Underclass Hero/Sum 41 - Speak of the Devil.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Underclass Hero/Sum 41 - The Jester.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Underclass Hero/Sum 41 - Underclass Hero.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Underclass Hero/Sum 41 - Walking Disaster.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Underclass Hero/Sum 41 - With Me.mp3 +C:/Users/Rik/Music/Artists/The Academy Is/Almost Here/The Academy Is... - Almost Here.mp3 +C:/Users/Rik/Music/Artists/The Academy Is/Almost Here/The Academy Is... - Attention.mp3 +C:/Users/Rik/Music/Artists/The Academy Is/Almost Here/The Academy Is... - Black Mamba.mp3 +C:/Users/Rik/Music/Artists/The Academy Is/Almost Here/The Academy Is... - Checkmarks.mp3 +C:/Users/Rik/Music/Artists/The Academy Is/Almost Here/The Academy Is... - Classifieds.mp3 +C:/Users/Rik/Music/Artists/The Academy Is/Almost Here/The Academy Is... - Down and Out.mp3 +C:/Users/Rik/Music/Artists/The Academy Is/Almost Here/The Academy Is... - Season.mp3 +C:/Users/Rik/Music/Artists/The Academy Is/Almost Here/The Academy Is... - Skeptics and True Believers.mp3 +C:/Users/Rik/Music/Artists/The Academy Is/Almost Here/The Academy Is... - The Phrase That Pays.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/Move Along/The All-American Rejects - 11.11 P.M.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/Move Along/The All-American Rejects - Change Your Mind.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/Move Along/The All-American Rejects - Dance Inside.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/Move Along/The All-American Rejects - Dirty Little Secret.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/Move Along/The All-American Rejects - I'm Waiting.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/Move Along/The All-American Rejects - Move Along.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/Move Along/The All-American Rejects - Stab My Back.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/Move Along/The All-American Rejects - Top of the World.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/When The World Comes Down/The All-American Rejects - Another Heart Calls.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/When The World Comes Down/The All-American Rejects - Back to Me.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/When The World Comes Down/The All-American Rejects - Believe.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/When The World Comes Down/The All-American Rejects - Breakin'.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/When The World Comes Down/The All-American Rejects - Damn Girl.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/When The World Comes Down/The All-American Rejects - Fallin' Apart.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/When The World Comes Down/The All-American Rejects - Gives You Hell.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/When The World Comes Down/The All-American Rejects - I Wanna.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/When The World Comes Down/The All-American Rejects - Mona Lisa.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/When The World Comes Down/The All-American Rejects - Real World.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/When The World Comes Down/The All-American Rejects - Sunshine.mp3 +C:/Users/Rik/Music/Artists/The All-American Rejects/When The World Comes Down/The All-American Rejects - The Wind Blows.mp3 +C:/Users/Rik/Music/Artists/The Fray/How To Save A Life/The Fray - All At Once.mp3 +C:/Users/Rik/Music/Artists/The Fray/How To Save A Life/The Fray - Dead Wrong.mp3 +C:/Users/Rik/Music/Artists/The Fray/How To Save A Life/The Fray - Fall Away.mp3 +C:/Users/Rik/Music/Artists/The Fray/How To Save A Life/The Fray - Heaven Forbid.mp3 +C:/Users/Rik/Music/Artists/The Fray/How To Save A Life/The Fray - How to Save a Life.mp3 +C:/Users/Rik/Music/Artists/The Fray/How To Save A Life/The Fray - Hundred.mp3 +C:/Users/Rik/Music/Artists/The Fray/How To Save A Life/The Fray - Little House.mp3 +C:/Users/Rik/Music/Artists/The Fray/How To Save A Life/The Fray - Look After You.mp3 +C:/Users/Rik/Music/Artists/The Fray/How To Save A Life/The Fray - Over My Head (Cable Car).mp3 +C:/Users/Rik/Music/Artists/The Fray/How To Save A Life/The Fray - She Is.mp3 +C:/Users/Rik/Music/Artists/The Fray/How To Save A Life/The Fray - Trust Me.mp3 +C:/Users/Rik/Music/Artists/The Hoosiers/The Illusion Of Safety/The Hoosiers - Bumpy Ride.mp3 +C:/Users/Rik/Music/Artists/The Hoosiers/The Illusion Of Safety/The Hoosiers - Choices.mp3 +C:/Users/Rik/Music/Artists/The Hoosiers/The Illusion Of Safety/The Hoosiers - Giddy Up.mp3 +C:/Users/Rik/Music/Artists/The Hoosiers/The Illusion Of Safety/The Hoosiers - Glorious.mp3 +C:/Users/Rik/Music/Artists/The Hoosiers/The Illusion Of Safety/The Hoosiers - Live By the Ocean.mp3 +C:/Users/Rik/Music/Artists/The Hoosiers/The Illusion Of Safety/The Hoosiers - Made to Measure.mp3 +C:/Users/Rik/Music/Artists/The Hoosiers/The Illusion Of Safety/The Hoosiers - Sarajevo.mp3 +C:/Users/Rik/Music/Artists/The Hoosiers/The Illusion Of Safety/The Hoosiers - Unlikely Hero.mp3 +C:/Users/Rik/Music/Artists/The Hoosiers/The Illusion Of Safety/The Hoosiers - Who Said Anything (About Falling In Love).mp3 +C:/Users/Rik/Music/Artists/The Killers/Day & Age/The Killers - A Crippling Blow.mp3 +C:/Users/Rik/Music/Artists/The Killers/Day & Age/The Killers - A Dustland Fairytale.mp3 +C:/Users/Rik/Music/Artists/The Killers/Day & Age/The Killers - Human.mp3 +C:/Users/Rik/Music/Artists/The Killers/Day & Age/The Killers - I Can't Stay.mp3 +C:/Users/Rik/Music/Artists/The Killers/Day & Age/The Killers - Joy Ride.mp3 +C:/Users/Rik/Music/Artists/The Killers/Day & Age/The Killers - Losing Touch.mp3 +C:/Users/Rik/Music/Artists/The Killers/Day & Age/The Killers - Neon Tiger.mp3 +C:/Users/Rik/Music/Artists/The Killers/Day & Age/The Killers - Spaceman.mp3 +C:/Users/Rik/Music/Artists/The Killers/Day & Age/The Killers - The World We Live In.mp3 +C:/Users/Rik/Music/Artists/The Killers/Day & Age/The Killers - This Is Your Life.mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - All These Things That I've Done.mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - Andy, You're a Star.mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - Believe Me Natalie.mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - Everything Will Be Alright.mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - Glamorous Indie Rock & Roll.mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - Indie Rock & Roll.mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - Jenny Was a Friend of Mine.mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - Midnight Show.mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - Mr Brightside.mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - Mr. Brightside.mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - On Top.mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - Smile Like You Mean It.mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - The Ballad of Michael Valentine (Bonus).mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - Under the Gun (Bonus).mp3 +C:/Users/Rik/Music/Artists/The Killers/Hot Fuss/The Killers - Who Let You Go (Bonus).mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - (Can't Get My) Head Around You.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - All I Want.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - Can't Repeat.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - Come Out and Play (Keep 'em Separated).mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - Defy You.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - Gone Away.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - Gotta Get Away.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - Hit That.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - Original Prankster.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - Pretty Fly (For a White Guy).mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - Self Esteem.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - The Kids Aren't Alright.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - Want You Bad.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Greatest Hits/The Offspring - Why Don't You Get a Job.mp3 +C:/Users/Rik/Music/Artists/The Script/Science & Faith/The Script - Dead Man Walking.mp3 +C:/Users/Rik/Music/Artists/The Script/Science & Faith/The Script - Exit Wounds.mp3 +C:/Users/Rik/Music/Artists/The Script/Science & Faith/The Script - For the First Time.mp3 +C:/Users/Rik/Music/Artists/The Script/Science & Faith/The Script - If You Ever Come Back.mp3 +C:/Users/Rik/Music/Artists/The Script/Science & Faith/The Script - Long Gone and Moved On.mp3 +C:/Users/Rik/Music/Artists/The Script/Science & Faith/The Script - Nothing.mp3 +C:/Users/Rik/Music/Artists/The Script/Science & Faith/The Script - Science & Faith.mp3 +C:/Users/Rik/Music/Artists/The Script/Science & Faith/The Script - This = Love.mp3 +C:/Users/Rik/Music/Artists/The Script/Science & Faith/The Script - You Won't Feel a Thing.mp3 +C:/Users/Rik/Music/Artists/The Script/The Script/The Script - Before the Worst.mp3 +C:/Users/Rik/Music/Artists/The Script/The Script/The Script - Breakeven.mp3 +C:/Users/Rik/Music/Artists/The Script/The Script/The Script - Fall For Anything.mp3 +C:/Users/Rik/Music/Artists/The Script/The Script/The Script - Rusty Halo.mp3 +C:/Users/Rik/Music/Artists/The Script/The Script/The Script - Talk You Down.mp3 +C:/Users/Rik/Music/Artists/The Script/The Script/The Script - The End Is Where I Begin.mp3 +C:/Users/Rik/Music/Artists/The Script/The Script/The Script - The Man Who Can't Be Moved.mp3 +C:/Users/Rik/Music/Artists/Three Days Grace/Life Starts Now/Three Days Grace - Bitter Taste.mp3 +C:/Users/Rik/Music/Artists/Three Days Grace/Life Starts Now/Three Days Grace - Break.mp3 +C:/Users/Rik/Music/Artists/Three Days Grace/Life Starts Now/Three Days Grace - Goin' Down.mp3 +C:/Users/Rik/Music/Artists/Three Days Grace/Life Starts Now/Three Days Grace - Last to Know.mp3 +C:/Users/Rik/Music/Artists/Three Days Grace/Life Starts Now/Three Days Grace - Life Starts Now.mp3 +C:/Users/Rik/Music/Artists/Three Days Grace/Life Starts Now/Three Days Grace - Lost In You.mp3 +C:/Users/Rik/Music/Artists/Three Days Grace/Life Starts Now/Three Days Grace - No More.mp3 +C:/Users/Rik/Music/Artists/Three Days Grace/Life Starts Now/Three Days Grace - Someone Who Cares.mp3 +C:/Users/Rik/Music/Artists/Three Days Grace/Life Starts Now/Three Days Grace - The Good Life.mp3 +C:/Users/Rik/Music/Artists/Three Days Grace/Life Starts Now/Three Days Grace - Without You.mp3 +C:/Users/Rik/Music/Artists/U2/No Line On The Horizon/U2 - Breathe.mp3 +C:/Users/Rik/Music/Artists/U2/No Line On The Horizon/U2 - Get On Your Boots.mp3 +C:/Users/Rik/Music/Artists/U2/No Line On The Horizon/U2 - I'll Go Crazy If I Don't Go Crazy Tonight.mp3 +C:/Users/Rik/Music/Artists/U2/No Line On The Horizon/U2 - Magnificent.mp3 +C:/Users/Rik/Music/Artists/U2/No Line On The Horizon/U2 - No Line On the Horizon.mp3 +C:/Users/Rik/Music/Artists/U2/No Line On The Horizon/U2 - Stand Up Comedy.mp3 +C:/Users/Rik/Music/Artists/U2/No Line On The Horizon/U2 - Unknown Caller.mp3 +C:/Users/Rik/Music/Artists/U2/No Line On The Horizon/U2 - White As Snow.mp3 +C:/Users/Rik/Music/Artists/U2/U2 - Beautiful Day.mp3 +C:/Users/Rik/Music/Artists/U2/U2 - Elevation.mp3 +C:/Users/Rik/Music/Artists/U2/U2 - I Still Haven't Found What I'm Looking For.mp3 +C:/Users/Rik/Music/Artists/U2/U2 - New Year's Day.mp3 +C:/Users/Rik/Music/Artists/U2/U2 - One.mp3 +C:/Users/Rik/Music/Artists/U2/U2 - Stuck In a Moment You Can't Get Out of.mp3 +C:/Users/Rik/Music/Artists/U2/U2 - Sunday Bloody Sunday .mp3 +C:/Users/Rik/Music/Artists/U2/U2 - Sweetest Thing.mp3 +C:/Users/Rik/Music/Artists/U2/U2 - The City of Blinding Lights.mp3 +C:/Users/Rik/Music/Artists/U2/U2 - Vertigo.mp3 +C:/Users/Rik/Music/Artists/U2/U2 - Where the Streets Have No Name.mp3 +C:/Users/Rik/Music/Artists/U2/U2 - With Or Without You.mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - All My Friends Are Insects (Bonus Track).mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - Brave New World.mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - Hang On.mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - I Want to Be Something (Bonus Track).mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - Memories.mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - Represent (Rocked Out Mix) %5Bbonus Track%5D.mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - Ruling Me.mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - Run Away.mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - Smart Girls.mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - Time Flies.mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - Trainwrecks.mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - Unspoken.mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - Viva La Vida (Bonus Track).mp3 +C:/Users/Rik/Music/Artists/Weezer/Hurley/Weezer - Where's My Sex.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Paper Walls/Yellowcard - Afraid.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Paper Walls/Yellowcard - Cut Me, Mick.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Paper Walls/Yellowcard - Date Line (I Am Gone).mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Paper Walls/Yellowcard - Dear Bobbie.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Paper Walls/Yellowcard - Fighting.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Paper Walls/Yellowcard - Five Become Four.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Paper Walls/Yellowcard - Keeper.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Paper Walls/Yellowcard - Light Up the Sky.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Paper Walls/Yellowcard - Paper Walls.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Paper Walls/Yellowcard - Shadows and Regrets.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Paper Walls/Yellowcard - Shrink the World.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Paper Walls/Yellowcard - The Takedown.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Paper Walls/Yellowcard - You and Me and One Spotlight.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/Yellowcard - October Nights.mp3 +C:/Users/Rik/Music/Artists/You Me At Six/Hold Me Down/You Me At Six - Contagious Chemistry.mp3 +C:/Users/Rik/Music/Artists/You Me At Six/Hold Me Down/You Me At Six - Fireworks.mp3 +C:/Users/Rik/Music/Artists/You Me At Six/Hold Me Down/You Me At Six - Hard to Swallow.mp3 +C:/Users/Rik/Music/Artists/You Me At Six/Hold Me Down/You Me At Six - Liquid Confidence.mp3 +C:/Users/Rik/Music/Artists/You Me At Six/Hold Me Down/You Me At Six - Playing the Blame Game.mp3 +C:/Users/Rik/Music/Artists/You Me At Six/Hold Me Down/You Me At Six - Safer to Hate Her.mp3 +C:/Users/Rik/Music/Artists/You Me At Six/Hold Me Down/You Me At Six - Stay With Me.mp3 +C:/Users/Rik/Music/Artists/You Me At Six/Hold Me Down/You Me At Six - Take Your Breath Away.mp3 +C:/Users/Rik/Music/Artists/You Me At Six/Hold Me Down/You Me At Six - There's No Such Thing As Accident.mp3 +C:/Users/Rik/Music/Artists/You Me At Six/Hold Me Down/You Me At Six - Trophy Eyes.mp3 +C:/Users/Rik/Music/Artists/You Me At Six/Hold Me Down/You Me At Six - Underdog.mp3 +C:/Users/Rik/Music/Old/Bad English - Time Stood Still.mp3 +C:/Users/Rik/Music/Old/Bon Jovi/Bon Jovi - In These Arms.mp3 +C:/Users/Rik/Music/Old/Bon Jovi/Bon Jovi - Livin' On a Prayer.mp3 +C:/Users/Rik/Music/Old/Don Henley - The Boys of Summer.mp3 +C:/Users/Rik/Music/Old/Duran Duran/Duran Duran - Ordinary World.mp3 +C:/Users/Rik/Music/Old/Duran Duran/Duran Duran - The Reflex.mp3 +C:/Users/Rik/Music/Old/Europe - The Final Countdown.mp3 +C:/Users/Rik/Music/Old/Genesis/Genesis - Land of Confusion.mp3 +C:/Users/Rik/Music/Old/Midnight Oil - Beds Are Burning.mp3 +C:/Users/Rik/Music/Old/No Doubt/No Doubt - It's My Life.mp3 +C:/Users/Rik/Music/Old/Survivor - Eye of the Tiger.mp3 +C:/Users/Rik/Music/Various/3 Doors Down/3 Doors Down - Here Without You.mp3 +C:/Users/Rik/Music/Various/3 Doors Down/3 Doors Down - Kryptonite.mp3 +C:/Users/Rik/Music/Various/A Silent Express - Will I Be Around.mp3 +C:/Users/Rik/Music/Various/Adam Lambert - Whataya Want From Me.mp3 +C:/Users/Rik/Music/Various/Alphabeat - The Spell.mp3 +C:/Users/Rik/Music/Various/Anouk/Anouk - Girl.mp3 +C:/Users/Rik/Music/Various/Anouk/Anouk - Nobody's Wife.mp3 +C:/Users/Rik/Music/Various/Anouk/Anouk - R U Kiddin' Me.mp3 +C:/Users/Rik/Music/Various/Avril Lavigne/Avril Lavigne - What the Hell.mp3 +C:/Users/Rik/Music/Various/Biffy Clyro - Many of Horror.mp3 +C:/Users/Rik/Music/Various/Brandon Flowers - Crossfire.mp3 +C:/Users/Rik/Music/Various/Carolina Liar - Show Me What Im Looking For.mp3 +C:/Users/Rik/Music/Various/Chumbawamba - Tubthumping.mp3 +C:/Users/Rik/Music/Various/Eagle Eye Cherry - Save Tonight.mp3 +C:/Users/Rik/Music/Various/Esm%C3%A9e Denters - Outta Here.mp3 +C:/Users/Rik/Music/Various/Falco Luneau - Nobody.mp3 +C:/Users/Rik/Music/Various/Freemasons - Uninvited.mp3 +C:/Users/Rik/Music/Various/Gavin DeGraw/Gavin Degraw - Chariot.mp3 +C:/Users/Rik/Music/Various/Gavin DeGraw/Gavin Degraw - Follow Through.mp3 +C:/Users/Rik/Music/Various/Gavin DeGraw/Gavin Degraw - In Love With a Girl.mp3 +C:/Users/Rik/Music/Various/Intwine - Happy.mp3 +C:/Users/Rik/Music/Various/Jaap - Don't Stop Believin'.mp3 +C:/Users/Rik/Music/Various/Jonas Brothers - Burnin' Up.mp3 +C:/Users/Rik/Music/Various/Joshua Radin - I'd Rather Be With You.mp3 +C:/Users/Rik/Music/Various/Kevin Rudolf - Let It Rock.mp3 +C:/Users/Rik/Music/Various/Kid Rock - All Summer Long.mp3 +C:/Users/Rik/Music/Various/Kylie Minogue/Kylie Minogue - All the Lovers.mp3 +C:/Users/Rik/Music/Various/Kylie Minogue/Kylie Minogue - Get Outta My Way.mp3 +C:/Users/Rik/Music/Various/Kylie Minogue/Kylie Minogue - Love At First Sight.mp3 +C:/Users/Rik/Music/Various/Kylie Minogue/Kylie Minogue - Wow.mp3 +C:/Users/Rik/Music/Various/Lenny Kravitz/Lenny Kravitz - Again.mp3 +C:/Users/Rik/Music/Various/Lenny Kravitz/Lenny Kravitz - Fly Away.mp3 +C:/Users/Rik/Music/Various/Liquido - Narcotic.mp3 +C:/Users/Rik/Music/Various/Live/Live - Heaven.mp3 +C:/Users/Rik/Music/Various/Live/Live - Overcome.mp3 +C:/Users/Rik/Music/Various/Live/Live - Run to the Water.mp3 +C:/Users/Rik/Music/Various/Live/Live - Selling the Drama.mp3 +C:/Users/Rik/Music/Various/Live/Live - The River.mp3 +C:/Users/Rik/Music/Various/Mando Diao - Dance With Somebody.mp3 +C:/Users/Rik/Music/Various/Maroon 5/Maroon 5 - Misery.mp3 +C:/Users/Rik/Music/Various/Maroon 5/Maroon 5 - Won't Go Home Without You.mp3 +C:/Users/Rik/Music/Various/Melee/Melee - Built to Last.mp3 +C:/Users/Rik/Music/Various/Melee/Melee - Imitation.mp3 +C:/Users/Rik/Music/Various/Mike Posner - Cooler Than Me.mp3 +C:/Users/Rik/Music/Various/Novastar/Novastar - Because.mp3 +C:/Users/Rik/Music/Various/Novastar/Novastar - Waiting So Long.mp3 +C:/Users/Rik/Music/Various/Oasis - Wonderwall.mp3 +C:/Users/Rik/Music/Various/One Night Only - Just For Tonight.mp3 +C:/Users/Rik/Music/Various/Robyn - With Every Heartbeat.mp3 +C:/Users/Rik/Music/Various/Roxette/Roxette - How Do You Do!.mp3 +C:/Users/Rik/Music/Various/Roxette/Roxette - It Must Have Been Love.mp3 +C:/Users/Rik/Music/Various/Roxette/Roxette - Joyride.mp3 +C:/Users/Rik/Music/Various/Roxette/Roxette - Listen to Your Heart.mp3 +C:/Users/Rik/Music/Various/Roxette/Roxette - The Look.mp3 +C:/Users/Rik/Music/Various/Scissor Sisters - Fire With Fire.mp3 +C:/Users/Rik/Music/Various/Scouting For Girls - Take a Change On Us.mp3 +C:/Users/Rik/Music/Various/Scouting for Girls/Scouting For Girls - Famous.mp3 +C:/Users/Rik/Music/Various/Scouting for Girls/Scouting For Girls - This Ain't a Love Song.mp3 +C:/Users/Rik/Music/Various/September/September - Can't Get Over.mp3 +C:/Users/Rik/Music/Various/September/September - Cry For You.mp3 +C:/Users/Rik/Music/Various/Sick Puppies - Maybe.mp3 +C:/Users/Rik/Music/Various/Simple Minds - Don't You (Forget About Me).mp3 +C:/Users/Rik/Music/Various/Spin Doctors - Two Princes.mp3 +C:/Users/Rik/Music/Various/Swedish House Mafia - One (Your Name).mp3 +C:/Users/Rik/Music/Various/Taio Cruz - Break Your Heart.mp3 +C:/Users/Rik/Music/Various/The Calling - Wherever You Will Go.mp3 +C:/Users/Rik/Music/Various/The Naked & Famous - Young Blood.mp3 +C:/Users/Rik/Music/Various/The Rasmus - In the Shadows.mp3 +C:/Users/Rik/Music/Various/Train/Train - Drops of Jupiter.mp3 +C:/Users/Rik/Music/Various/Train/Train - Hey, Soul Sister.mp3 +C:/Users/Rik/Music/Various/Train/Train - If It's Love.mp3 +C:/Users/Rik/Music/Various/Wheatus - Teenage Dirtbag.mp3 +C:/Users/Rik/Music/Various/Within Temptation - Faster.mp3 +C:/Users/Rik/Music/Various/Jason Derulo - In My Head.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Wasting Light/Foo Fighters - Better Off.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Wasting Light/Foo Fighters - I Should Have Known.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Chase The Light/Jimmy Eat World - Always Be.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Chase The Light/Jimmy Eat World - Big Casino.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Chase The Light/Jimmy Eat World - Carry You.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Chase The Light/Jimmy Eat World - Chase This Light.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Chase The Light/Jimmy Eat World - Dizzy.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Chase The Light/Jimmy Eat World - Electable (Give It Up).mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Chase The Light/Jimmy Eat World - Feeling Lucky.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Chase The Light/Jimmy Eat World - Firefight.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Chase The Light/Jimmy Eat World - Gotta Be Somebody's Blues.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Chase The Light/Jimmy Eat World - Here It Goes.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Chase The Light/Jimmy Eat World - Let It Happen.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Still Not Getting Any/Simple Plan - Crazy.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Still Not Getting Any/Simple Plan - Everytime.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Still Not Getting Any/Simple Plan - Jump.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Still Not Getting Any/Simple Plan - Me Against The World.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Still Not Getting Any/Simple Plan - One.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Still Not Getting Any/Simple Plan - Perfect World.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Still Not Getting Any/Simple Plan - Promise.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Still Not Getting Any/Simple Plan - Shut Up.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Still Not Getting Any/Simple Plan - Thank You.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Still Not Getting Any/Simple Plan - Untitled.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Still Not Getting Any/Simple Plan - Welcome To My Life.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Beyond Hell-Above Heaven/Volbeat - 16 Dollars.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Beyond Hell-Above Heaven/Volbeat - 7 Shots.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Beyond Hell-Above Heaven/Volbeat - A Better Believer.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Beyond Hell-Above Heaven/Volbeat - A New Day.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Beyond Hell-Above Heaven/Volbeat - A Warrior's Call.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Beyond Hell-Above Heaven/Volbeat - Being 1.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Beyond Hell-Above Heaven/Volbeat - Fallen.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Beyond Hell-Above Heaven/Volbeat - Heaven Nor Hell.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Beyond Hell-Above Heaven/Volbeat - Magic Zone.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Beyond Hell-Above Heaven/Volbeat - Thanks.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Beyond Hell-Above Heaven/Volbeat - The Mirror and the Ripper.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Beyond Hell-Above Heaven/Volbeat - Who They Are.mp3 +C:/Users/Rik/Music/Various/Beady Eye - The Roller.mp3 +C:/Users/Rik/Music/Various/Depeche Mode - Just Can't Get Enough.mp3 +C:/Users/Rik/Music/Various/Kelly Clarkson/Kelly Clarkson - Because of You.mp3 +C:/Users/Rik/Music/Various/Kelly Clarkson/Kelly Clarkson - Behind These Hazel Eyes.mp3 +C:/Users/Rik/Music/Various/Kelly Clarkson/Kelly Clarkson - Since U Been Gone.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/American Slang/The Gaslight Anthem - American Slang.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/American Slang/The Gaslight Anthem - Boxer.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/American Slang/The Gaslight Anthem - Bring It On.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/American Slang/The Gaslight Anthem - Old Haunts.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/American Slang/The Gaslight Anthem - Orphans.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/American Slang/The Gaslight Anthem - Stay Lucky.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/American Slang/The Gaslight Anthem - The Diamond Church Street Choir.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/American Slang/The Gaslight Anthem - The Queen Of Lower Chelsea.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/American Slang/The Gaslight Anthem - The Spirit Of Jazz.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/American Slang/The Gaslight Anthem - We Did It When We Were Young.mp3 +C:/Users/Rik/Music/Artists/Blind/Blind/Blind - Break Away.mp3 +C:/Users/Rik/Music/Artists/Blind/Blind/Blind - Every You Every Me.mp3 +C:/Users/Rik/Music/Artists/Blind/Blind/Blind - Jesus Only Knows.mp3 +C:/Users/Rik/Music/Artists/Blind/Blind/Blind - Love Is Gone.mp3 +C:/Users/Rik/Music/Artists/Blind/Blind/Blind - Ordinary Day.mp3 +C:/Users/Rik/Music/Artists/Blind/Blind/Blind - People.mp3 +C:/Users/Rik/Music/Artists/Blind/Blind/Blind - Save Me Now.mp3 +C:/Users/Rik/Music/Artists/Blind/Blind/Blind - These Are the Days.mp3 +C:/Users/Rik/Music/Artists/Blind/Blind/Blind - Today I Break Loose.mp3 +C:/Users/Rik/Music/Artists/Blind/Blind/Blind - Triple X.mp3 +C:/Users/Rik/Music/Artists/Blind/Blind/Blind - Wake Me Up.mp3 +C:/Users/Rik/Music/Artists/Blind/Blind/Blind - We Can Stay.mp3 +C:/Users/Rik/Music/Artists/Blind/Blind/Blind - You.mp3 +C:/Users/Rik/Music/Artists/Cute Is What We Aim For/Rotation/Cute Is What We Aim For - Do What You Do.mp3 +C:/Users/Rik/Music/Artists/Cute Is What We Aim For/Rotation/Cute Is What We Aim For - Doctor.mp3 +C:/Users/Rik/Music/Artists/Cute Is What We Aim For/Rotation/Cute Is What We Aim For - Hollywood.mp3 +C:/Users/Rik/Music/Artists/Cute Is What We Aim For/Rotation/Cute Is What We Aim For - Loser.mp3 +C:/Users/Rik/Music/Artists/Cute Is What We Aim For/Rotation/Cute Is What We Aim For - Marriage to Millions.mp3 +C:/Users/Rik/Music/Artists/Cute Is What We Aim For/Rotation/Cute Is What We Aim For - Miss Sobriety.mp3 +C:/Users/Rik/Music/Artists/Cute Is What We Aim For/Rotation/Cute Is What We Aim For - Navigate Me.mp3 +C:/Users/Rik/Music/Artists/Cute Is What We Aim For/Rotation/Cute Is What We Aim For - Practice Makes Perfect.mp3 +C:/Users/Rik/Music/Artists/Cute Is What We Aim For/Rotation/Cute Is What We Aim For - Safe Ride.mp3 +C:/Users/Rik/Music/Artists/Cute Is What We Aim For/Rotation/Cute Is What We Aim For - The Lock Down Denial.mp3 +C:/Users/Rik/Music/Artists/Cute Is What We Aim For/Rotation/Cute Is What We Aim For - Time.mp3 +C:/Users/Rik/Music/Artists/Kids In Glass Houses/Dirt/Kids In Glass Houses - Artbreaker I.mp3 +C:/Users/Rik/Music/Artists/Kids In Glass Houses/Dirt/Kids In Glass Houses - Artbreaker II.mp3 +C:/Users/Rik/Music/Artists/Kids In Glass Houses/Dirt/Kids In Glass Houses - For Better Or Hearse.mp3 +C:/Users/Rik/Music/Artists/Kids In Glass Houses/Dirt/Kids In Glass Houses - Giving Up.mp3 +C:/Users/Rik/Music/Artists/Kids In Glass Houses/Dirt/Kids In Glass Houses - Hunt the Haunted.mp3 +C:/Users/Rik/Music/Artists/Kids In Glass Houses/Dirt/Kids In Glass Houses - Lilli Rose.mp3 +C:/Users/Rik/Music/Artists/Kids In Glass Houses/Dirt/Kids In Glass Houses - Matters At All.mp3 +C:/Users/Rik/Music/Artists/Kids In Glass Houses/Dirt/Kids In Glass Houses - Maybe Tomorrow.mp3 +C:/Users/Rik/Music/Artists/Kids In Glass Houses/Dirt/Kids In Glass Houses - Sunshine.mp3 +C:/Users/Rik/Music/Artists/Kids In Glass Houses/Dirt/Kids In Glass Houses - The Best Is Yet To Come.mp3 +C:/Users/Rik/Music/Artists/Kids In Glass Houses/Dirt/Kids In Glass Houses - The Morning Afterlife.mp3 +C:/Users/Rik/Music/Artists/Kids In Glass Houses/Dirt/Kids In Glass Houses - Undercover Lover.mp3 +C:/Users/Rik/Music/Artists/Kids In Glass Houses/Dirt/Kids In Glass Houses - Youngblood (Let It Out).mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Get Your Heart On!/Simple Plan - Anywhere Else But Here.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Get Your Heart On!/Simple Plan - Astronaut.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Get Your Heart On!/Simple Plan - Can't Keep My Hands Off You.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Get Your Heart On!/Simple Plan - Freaking Me Out.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Get Your Heart On!/Simple Plan - Gone Too Soon.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Get Your Heart On!/Simple Plan - Jet Lag.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Get Your Heart On!/Simple Plan - Last One Standing.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Get Your Heart On!/Simple Plan - Loser Of The Year.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Get Your Heart On!/Simple Plan - This Song Saved My Life.mp3 +C:/Users/Rik/Music/Artists/Simple Plan/Get Your Heart On!/Simple Plan - You Suck At Love.mp3 +C:/Users/Rik/Music/Various/The Von Bondies - C%60Mon C%60Mon.mp3 +C:/Users/Rik/Music/Various/White Stripes - Seven Nation Army.mp3 +C:/Users/Rik/Music/Artists/Futures/The Holiday/Futures - 16.mp3 +C:/Users/Rik/Music/Artists/Futures/The Holiday/Futures - Holiday.mp3 +C:/Users/Rik/Music/Artists/Futures/The Holiday/Futures - Sal Paradise.mp3 +C:/Users/Rik/Music/Artists/Futures/The Holiday/Futures - Take Me Home.mp3 +C:/Users/Rik/Music/Artists/Futures/The Holiday/Futures - Thank You.mp3 +C:/Users/Rik/Music/Artists/Futures/The Holiday/Futures - The Boy Who Cried Wolf.mp3 +C:/Users/Rik/Music/Artists/Futures/The Holiday/Futures - The Summer.mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - Audience of One.mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - Collapse (Post-Amerika).mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - Elective Amnesia.mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - Entertainment.mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - From Heads Unworthy.mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - Hairline Fracture.mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - Hero of War.mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - Kotov Syndrome.mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - Long Forgotten Sons.mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - Prayer of the Refugee.mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - Re-Education (Through Labor).mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - Savior.mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - The Dirt Whispered.mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - The Strength to Go On.mp3 +C:/Users/Rik/Music/Artists/Rise Against/Appeal To Reason/Rise Against - Whereabouts Unknown.mp3 +C:/Users/Rik/Music/Artists/White Lies/To Lose My Life/White Lies - A Place To Hide.mp3 +C:/Users/Rik/Music/Artists/White Lies/To Lose My Life/White Lies - Death.mp3 +C:/Users/Rik/Music/Artists/White Lies/To Lose My Life/White Lies - E.S.T..mp3 +C:/Users/Rik/Music/Artists/White Lies/To Lose My Life/White Lies - Farewell To The Fairground.mp3 +C:/Users/Rik/Music/Artists/White Lies/To Lose My Life/White Lies - Fifty On Our Foreheads.mp3 +C:/Users/Rik/Music/Artists/White Lies/To Lose My Life/White Lies - From The Stars.mp3 +C:/Users/Rik/Music/Artists/White Lies/To Lose My Life/White Lies - Nothing To Give.mp3 +C:/Users/Rik/Music/Artists/White Lies/To Lose My Life/White Lies - The Price Of Love.mp3 +C:/Users/Rik/Music/Artists/White Lies/To Lose My Life/White Lies - To Lose My Life.mp3 +C:/Users/Rik/Music/Artists/White Lies/To Lose My Life/White Lies - Unfinished Business.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/When You're Through Thinking, Say Yes/Yellowcard - Be the Young.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/When You're Through Thinking, Say Yes/Yellowcard - For You and Your Denial.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/When You're Through Thinking, Say Yes/Yellowcard - Hang You Up.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/When You're Through Thinking, Say Yes/Yellowcard - Hide.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/When You're Through Thinking, Say Yes/Yellowcard - Life of Leaving Home.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/When You're Through Thinking, Say Yes/Yellowcard - Promises.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/When You're Through Thinking, Say Yes/Yellowcard - See Me Smiling.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/When You're Through Thinking, Say Yes/Yellowcard - Sing for Me (Acoustic).mp3 +C:/Users/Rik/Music/Artists/Yellowcard/When You're Through Thinking, Say Yes/Yellowcard - Sing for Me.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/When You're Through Thinking, Say Yes/Yellowcard - Soundtrack.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/When You're Through Thinking, Say Yes/Yellowcard - The Sound of You and Me.mp3 +C:/Users/Rik/Music/Artists/Yellowcard/When You're Through Thinking, Say Yes/Yellowcard - With You Around.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Infinity On High/Fall Out Boy - Bang The Doldrums.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Infinity On High/Fall Out Boy - Don't You Know Who I Think I Am.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Infinity On High/Fall Out Boy - Fame.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Infinity On High/Fall Out Boy - Hum Hallelujah.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Infinity On High/Fall Out Boy - I'm Like A Lawyer With The Way I'm Always Trying To Get You Off (me+you).mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Infinity On High/Fall Out Boy - I've Got All This Ringing In My Ears And None On My Fingers.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Infinity On High/Fall Out Boy - Thanks For The Memories.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Infinity On High/Fall Out Boy - The (After) Life Of The Party.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Infinity On High/Fall Out Boy - The Carpal Tunnel Of Love.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Infinity On High/Fall Out Boy - The Take Over, The Breaks Over.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Infinity On High/Fall Out Boy - This Ain't A Scene, It's An Arms Race.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Infinity On High/Fall Out Boy - Thriller.mp3 +C:/Users/Rik/Music/Artists/Fall Out Boy/Infinity On High/Fall Out Boy - You're Crashing, But You're No Wave.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Invented/Jimmy Eat World - Action Needs An Audience.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Invented/Jimmy Eat World - Coffee And Cigarettes.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Invented/Jimmy Eat World - Cut.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Invented/Jimmy Eat World - Evidence.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Invented/Jimmy Eat World - Heart Is Hard To Find.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Invented/Jimmy Eat World - Higher Devotion.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Invented/Jimmy Eat World - Invented.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Invented/Jimmy Eat World - Littlething.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Invented/Jimmy Eat World - Mixtape.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Invented/Jimmy Eat World - Movielike.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Invented/Jimmy Eat World - My Best Theory.mp3 +C:/Users/Rik/Music/Artists/Jimmy Eat World/Invented/Jimmy Eat World - Stop.mp3 +C:/Users/Rik/Music/Artists/Red/Until We Have Faces/Red - Best Is Yet to Come.mp3 +C:/Users/Rik/Music/Artists/Red/Until We Have Faces/Red - Buried Beneath.mp3 +C:/Users/Rik/Music/Artists/Red/Until We Have Faces/Red - Faceless.mp3 +C:/Users/Rik/Music/Artists/Red/Until We Have Faces/Red - Feed the Machine.mp3 +C:/Users/Rik/Music/Artists/Red/Until We Have Faces/Red - Hymn for the Missing.mp3 +C:/Users/Rik/Music/Artists/Red/Until We Have Faces/Red - Let It Burn.mp3 +C:/Users/Rik/Music/Artists/Red/Until We Have Faces/Red - Lie to Me (Denial).mp3 +C:/Users/Rik/Music/Artists/Red/Until We Have Faces/Red - Not Alone.mp3 +C:/Users/Rik/Music/Artists/Red/Until We Have Faces/Red - The Outside.mp3 +C:/Users/Rik/Music/Artists/Red/Until We Have Faces/Red - Watch You Crawl.mp3 +C:/Users/Rik/Music/Artists/Red/Until We Have Faces/Red - Who We Are.mp3 +C:/Users/Rik/Music/Artists/Framing Hanley/A Promise To Burn/Framing Hanley - Back To Go Again.mp3 +C:/Users/Rik/Music/Artists/Framing Hanley/A Promise To Burn/Framing Hanley - Bittersweet Sundown.mp3 +C:/Users/Rik/Music/Artists/Framing Hanley/A Promise To Burn/Framing Hanley - Fool With Dreams.mp3 +C:/Users/Rik/Music/Artists/Framing Hanley/A Promise To Burn/Framing Hanley - Intro.mp3 +C:/Users/Rik/Music/Artists/Framing Hanley/A Promise To Burn/Framing Hanley - Livin' So Divine.mp3 +C:/Users/Rik/Music/Artists/Framing Hanley/A Promise To Burn/Framing Hanley - Photographs & Gasoline.mp3 +C:/Users/Rik/Music/Artists/Framing Hanley/A Promise To Burn/Framing Hanley - The Burn.mp3 +C:/Users/Rik/Music/Artists/Framing Hanley/A Promise To Burn/Framing Hanley - The Promise.mp3 +C:/Users/Rik/Music/Artists/Framing Hanley/A Promise To Burn/Framing Hanley - Wake Up.mp3 +C:/Users/Rik/Music/Artists/Framing Hanley/A Promise To Burn/Framing Hanley - WarZone.mp3 +C:/Users/Rik/Music/Artists/Framing Hanley/A Promise To Burn/Framing Hanley - Weight of The World.mp3 +C:/Users/Rik/Music/Artists/Framing Hanley/A Promise To Burn/Framing Hanley - You Stupid Girl.mp3 +C:/Users/Rik/Music/Artists/Framing Hanley/A Promise To Burn/Framing Hanley - You.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - (Fin).mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - A Whisper & A Clamour.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - Adelaide.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - Alexithymia.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - Debut.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - Dismantle. Repair.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - Godspeed.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - Hello Alone.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - Inevitable.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - Reclusion.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - The Promise.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - The Unwinding Cable Car.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - There Is A Light That Never Goes Dope.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - There Is No Mathematics To Love And Loss.mp3 +C:/Users/Rik/Music/Artists/Anberlin/Cities/Anberlin - Uncanny.mp3 +C:/Users/Rik/Music/Artists/Anberlin/New Surrender/Anberlin - Blame Me! Blame Me!.mp3 +C:/Users/Rik/Music/Artists/Anberlin/New Surrender/Anberlin - Breaking.mp3 +C:/Users/Rik/Music/Artists/Anberlin/New Surrender/Anberlin - Breathe.mp3 +C:/Users/Rik/Music/Artists/Anberlin/New Surrender/Anberlin - Burn Out Brighter (Northern Lights).mp3 +C:/Users/Rik/Music/Artists/Anberlin/New Surrender/Anberlin - Disappear.mp3 +C:/Users/Rik/Music/Artists/Anberlin/New Surrender/Anberlin - Feel Good Drag.mp3 +C:/Users/Rik/Music/Artists/Anberlin/New Surrender/Anberlin - Haight St.mp3 +C:/Users/Rik/Music/Artists/Anberlin/New Surrender/Anberlin - Misearbile Visu (Ex Malo Bonum).mp3 +C:/Users/Rik/Music/Artists/Anberlin/New Surrender/Anberlin - Retrace.mp3 +C:/Users/Rik/Music/Artists/Anberlin/New Surrender/Anberlin - Soft Skeletons.mp3 +C:/Users/Rik/Music/Artists/Anberlin/New Surrender/Anberlin - The Resistance.mp3 +C:/Users/Rik/Music/Artists/Anberlin/New Surrender/Anberlin - Younglife.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/Neon Bible/Arcade Fire - Antichrist Television Blues.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/Neon Bible/Arcade Fire - Black Mirror.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/Neon Bible/Arcade Fire - Black WaveBad Vibrations.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/Neon Bible/Arcade Fire - Intervention.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/Neon Bible/Arcade Fire - Keep The Car Running.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/Neon Bible/Arcade Fire - No Cars Go.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/Neon Bible/Arcade Fire - Ocean Of Noise.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/Neon Bible/Arcade Fire - Well & The Lighthouse, The.mp3 +C:/Users/Rik/Music/Artists/Arcade Fire/Neon Bible/Arcade Fire - Windowsill.mp3 +C:/Users/Rik/Music/Artists/Green Day/21st Century Breakdown/Green Day - %C2%A1Viva la Gloria!.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/Sink or Swim/The Gaslight Anthem - 1990.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/Sink or Swim/The Gaslight Anthem - Angry Johnny and the Radio.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/Sink or Swim/The Gaslight Anthem - Bomboxes and Dictionaries.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/Sink or Swim/The Gaslight Anthem - Drive.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/Sink or Swim/The Gaslight Anthem - I Coul'da Been a Contender.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/Sink or Swim/The Gaslight Anthem - I'da Called You Woody, Joe.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/Sink or Swim/The Gaslight Anthem - Red in the Morning.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/Sink or Swim/The Gaslight Anthem - We Came to Dance.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/Sink or Swim/The Gaslight Anthem - We're Getting A Divorce, You Keep The Dinner.mp3 +C:/Users/Rik/Music/Artists/The Gaslight Anthem/Sink or Swim/The Gaslight Anthem - Wooderson.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - Back To Prom.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - Broken Man And The Dawn.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - End Of The Road.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - Find That Soul.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - Guitar Gangsters & Cadillac Blood.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - Hallelujah Goat.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - I'm So Lonesome I Could Cry.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - Light A Way.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - Making Believe.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - Mary Ann' s Place.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - Maybellene I Hofteholder.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - Still Counting.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - We.mp3 +C:/Users/Rik/Music/Artists/Volbeat/Guitar Gangsters & Cadillac Blood/Volbeat - Wild Rover Of Hell.mp3 +C:/Users/Rik/Music/Artists/My Chemical Romance/Danger Days - The True Lives Of The Fabulous Killjoys/My Chemical Romance - Bulletproof Heart.mp3 +C:/Users/Rik/Music/Artists/My Chemical Romance/Danger Days - The True Lives Of The Fabulous Killjoys/My Chemical Romance - Destroya.mp3 +C:/Users/Rik/Music/Artists/My Chemical Romance/Danger Days - The True Lives Of The Fabulous Killjoys/My Chemical Romance - Party Poison.mp3 +C:/Users/Rik/Music/Artists/My Chemical Romance/Danger Days - The True Lives Of The Fabulous Killjoys/My Chemical Romance - Planetary (Go!).mp3 +C:/Users/Rik/Music/Artists/My Chemical Romance/Danger Days - The True Lives Of The Fabulous Killjoys/My Chemical Romance - Save Yourself- I'll Hold Them Back.mp3 +C:/Users/Rik/Music/Artists/My Chemical Romance/Danger Days - The True Lives Of The Fabulous Killjoys/My Chemical Romance - S-C-A-R-E-C-R-O-W.mp3 +C:/Users/Rik/Music/Artists/My Chemical Romance/Danger Days - The True Lives Of The Fabulous Killjoys/My Chemical Romance - Sing.mp3 +C:/Users/Rik/Music/Artists/My Chemical Romance/Danger Days - The True Lives Of The Fabulous Killjoys/My Chemical Romance - Summertime.mp3 +C:/Users/Rik/Music/Artists/My Chemical Romance/Danger Days - The True Lives Of The Fabulous Killjoys/My Chemical Romance - The Kids From Yesterday.mp3 +C:/Users/Rik/Music/Artists/My Chemical Romance/Danger Days - The True Lives Of The Fabulous Killjoys/My Chemical Romance - The Only Hope For Me Is You.mp3 +C:/Users/Rik/Music/Artists/My Chemical Romance/Danger Days - The True Lives Of The Fabulous Killjoys/My Chemical Romance - Vampire Money.mp3 +C:/Users/Rik/Music/Artists/Longwave/Secrets Are Sinister/Longwave - Eyes Like Headlights.mp3 +C:/Users/Rik/Music/Artists/Longwave/Secrets Are Sinister/Longwave - I Don't Dare.mp3 +C:/Users/Rik/Music/Artists/Longwave/Secrets Are Sinister/Longwave - It's True.mp3 +C:/Users/Rik/Music/Artists/Longwave/Secrets Are Sinister/Longwave - Life Is Wrong.mp3 +C:/Users/Rik/Music/Artists/Longwave/Secrets Are Sinister/Longwave - No Direction.mp3 +C:/Users/Rik/Music/Artists/Longwave/Secrets Are Sinister/Longwave - Satellites.mp3 +C:/Users/Rik/Music/Artists/Longwave/Secrets Are Sinister/Longwave - Secrets Are Sinister.mp3 +C:/Users/Rik/Music/Artists/Longwave/Secrets Are Sinister/Longwave - Shining Hours.mp3 +C:/Users/Rik/Music/Artists/Longwave/Secrets Are Sinister/Longwave - Sideways Sideways Rain.mp3 +C:/Users/Rik/Music/Artists/Longwave/Secrets Are Sinister/Longwave - Sirens In The Deep Sea.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - Annie Wants a Baby.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - Brendan's Death Song.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - Dance, Dance, Dance.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - Did I Let You Know.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - Ethiopia.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - Even You Brutus.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - Factory of Faith.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - Goodbye Hooray.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - Happiness Loves Company.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - Look Around.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - Meet Me At the Corner.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - Monarchy of Roses.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - Police Station.mp3 +C:/Users/Rik/Music/Artists/Red Hot Chili Peppers/I'm With You/Red Hot Chili Peppers - The Adventures of Rain Dance Maggie.mp3 +C:/Users/Rik/Music/Artists/Amber Pacific/Virtues/Amber Pacific - An Anthem For The Young At Heart.mp3 +C:/Users/Rik/Music/Artists/Amber Pacific/Virtues/Amber Pacific - Burdens Of The Past.mp3 +C:/Users/Rik/Music/Artists/Amber Pacific/Virtues/Amber Pacific - Conviction.mp3 +C:/Users/Rik/Music/Artists/Amber Pacific/Virtues/Amber Pacific - Shine.mp3 +C:/Users/Rik/Music/Artists/Amber Pacific/Virtues/Amber Pacific - Something To Be Said.mp3 +C:/Users/Rik/Music/Artists/Amber Pacific/Virtues/Amber Pacific - The Best Mistake.mp3 +C:/Users/Rik/Music/Artists/Amber Pacific/Virtues/Amber Pacific - The Girl Who Destroys.mp3 +C:/Users/Rik/Music/Artists/Amber Pacific/Virtues/Amber Pacific - The Good Life.mp3 +C:/Users/Rik/Music/Artists/Amber Pacific/Virtues/Amber Pacific - Three Words.mp3 +C:/Users/Rik/Music/Artists/Amber Pacific/Virtues/Amber Pacific - We Can't Fake This.mp3 +C:/Users/Rik/Music/Artists/Amber Pacific/Virtues/Amber Pacific - What Matters Most.mp3 +C:/Users/Rik/Music/Old/Nirvana - Smells Like Teen Spirit.mp3 +C:/Users/Rik/Music/Artists/10 Years Feeding/Feeding the Wolves/10 Years - Don't Fight It.mp3 +C:/Users/Rik/Music/Artists/Cold War Kids/Mine Is Yours/Cold War Kids - Broken Open.mp3 +C:/Users/Rik/Music/Artists/Cold War Kids/Mine Is Yours/Cold War Kids - Bulldozer.mp3 +C:/Users/Rik/Music/Artists/Cold War Kids/Mine Is Yours/Cold War Kids - Cold Toes On The Cold Floor.mp3 +C:/Users/Rik/Music/Artists/Cold War Kids/Mine Is Yours/Cold War Kids - Finally Begin.mp3 +C:/Users/Rik/Music/Artists/Cold War Kids/Mine Is Yours/Cold War Kids - Louder Than Ever.mp3 +C:/Users/Rik/Music/Artists/Cold War Kids/Mine Is Yours/Cold War Kids - Mine Is Yours.mp3 +C:/Users/Rik/Music/Artists/Cold War Kids/Mine Is Yours/Cold War Kids - Out Of The Wilderness.mp3 +C:/Users/Rik/Music/Artists/Cold War Kids/Mine Is Yours/Cold War Kids - Royal Blue.mp3 +C:/Users/Rik/Music/Artists/Cold War Kids/Mine Is Yours/Cold War Kids - Sensitive Kid.mp3 +C:/Users/Rik/Music/Artists/Cold War Kids/Mine Is Yours/Cold War Kids - Skip The Charades.mp3 +C:/Users/Rik/Music/Artists/Sum 41/Screaming Bloody Murder/Sum 41 - We're the Same.mp3 +C:/Users/Rik/Music/Artists/Maximo Park/Our Earthly Pleasures/Maximo Park - A Fortnight's Time.mp3 +C:/Users/Rik/Music/Artists/Maximo Park/Our Earthly Pleasures/Maximo Park - Books From Boxes.mp3 +C:/Users/Rik/Music/Artists/Maximo Park/Our Earthly Pleasures/Maximo Park - By The Monument.mp3 +C:/Users/Rik/Music/Artists/Maximo Park/Our Earthly Pleasures/Maximo Park - Girls Who Play Guitars.mp3 +C:/Users/Rik/Music/Artists/Maximo Park/Our Earthly Pleasures/Maximo Park - Karaoke Plays.mp3 +C:/Users/Rik/Music/Artists/Maximo Park/Our Earthly Pleasures/Maximo Park - Nosebleed.mp3 +C:/Users/Rik/Music/Artists/Maximo Park/Our Earthly Pleasures/Maximo Park - Our Velocity.mp3 +C:/Users/Rik/Music/Artists/Maximo Park/Our Earthly Pleasures/Maximo Park - Parisian Skies.mp3 +C:/Users/Rik/Music/Artists/Maximo Park/Our Earthly Pleasures/Maximo Park - Russian Literature.mp3 +C:/Users/Rik/Music/Artists/Maximo Park/Our Earthly Pleasures/Maximo Park - Sandblasted And Set Free.mp3 +C:/Users/Rik/Music/Artists/Maximo Park/Our Earthly Pleasures/Maximo Park - The Unshockable.mp3 +C:/Users/Rik/Music/Artists/Maximo Park/Our Earthly Pleasures/Maximo Park - Your Urge.mp3 +C:/Users/Rik/Music/Artists/Stereophonics/Keep Calm and Carry On/Stereophonics - 100MPH.mp3 +C:/Users/Rik/Music/Artists/Stereophonics/Keep Calm and Carry On/Stereophonics - Beerbottle.mp3 +C:/Users/Rik/Music/Artists/Stereophonics/Keep Calm and Carry On/Stereophonics - Could You Be The One.mp3 +C:/Users/Rik/Music/Artists/Stereophonics/Keep Calm and Carry On/Stereophonics - I Got Your Number.mp3 +C:/Users/Rik/Music/Artists/Stereophonics/Keep Calm and Carry On/Stereophonics - Innocent.mp3 +C:/Users/Rik/Music/Artists/Stereophonics/Keep Calm and Carry On/Stereophonics - Live 'N' Love.mp3 +C:/Users/Rik/Music/Artists/Stereophonics/Keep Calm and Carry On/Stereophonics - She's Alright.mp3 +C:/Users/Rik/Music/Artists/Stereophonics/Keep Calm and Carry On/Stereophonics - Show Me How.mp3 +C:/Users/Rik/Music/Artists/Stereophonics/Keep Calm and Carry On/Stereophonics - Stuck In A Rut.mp3 +C:/Users/Rik/Music/Artists/Stereophonics/Keep Calm and Carry On/Stereophonics - Trouble.mp3 +C:/Users/Rik/Music/Artists/Stereophonics/Keep Calm and Carry On/Stereophonics - Uppercut.mp3 +C:/Users/Rik/Music/Artists/Stereophonics/Keep Calm and Carry On/Stereophonics - Wonder.mp3 +C:/Users/Rik/Music/Artists/Foo Fighters/Greatest Hits/Foo Fighters - Everlong (Acoustic).mp3 +C:/Users/Rik/Music/Artists/Lifehouse/Smoke & Mirrors/Lifehouse - Everything (Live).mp3 +C:/Users/Rik/Music/Artists/Amber Pacific/Virtues/Amber Pacific - Forever.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - After Midnight.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - Even If She Falls.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - Fighting the Gravity.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - Ghost On The Dance Floor.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - Heart's All Gone (Interlude).mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - Heart's All Gone.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - Kaleidoscope.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - Love Is Dangerous.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - Mh 4.18.2011.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - Natives.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - Snake Charmer.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - This Is Home.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - Up All Night.mp3 +C:/Users/Rik/Music/Artists/Blink-182/Neighborhoods/Blink-182 - Wishing Well.mp3 +C:/Users/Rik/Music/Artists/Longwave/Secrets Are Sinister/Longwave - The Devil And The Liar.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - All I Can Do.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Believe It.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Can You Handle Me.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Catwalk Criminal.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Damn Those Eyes.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Dreamer.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Fearless.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Hold On to the World.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - I Will Keep My Head Down.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - In Over My Head.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - It's London Calling.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Let It Be.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Love Over Healing.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - My Best Wasn't Good Enough.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - No Surrender.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Rain Down On Me.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Scream.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Shot of a Gun.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - So Glad You Made It.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Something to Say.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Wanna Make It Happen.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - Where Do I Go Now.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - A Hopeful Transmission.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - Charlie Brown.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - Don't Let It Break Your Heart.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - Every Teardrop Is a Waterfall.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - Hurts Like Heaven.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - M.M.I.X..mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - Major Minus.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - Mylo Xyloto.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - Paradise.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - Princess of China.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - U.F.O..mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - Up in Flames.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - Up with the Birds.mp3 +C:/Users/Rik/Music/Artists/Coldplay/Mylo Xyloto/Coldplay - Us Against the World.mp3 +C:/Users/Rik/Music/Artists/Kane/Singles Only/Kane - High Places.mp3 +C:/Users/Rik/Music/Artists/White Lies/Ritual/White Lies - Bad Love.mp3 +C:/Users/Rik/Music/Artists/White Lies/Ritual/White Lies - Bigger Than Us.mp3 +C:/Users/Rik/Music/Artists/White Lies/Ritual/White Lies - Come Down.mp3 +C:/Users/Rik/Music/Artists/White Lies/Ritual/White Lies - Holy Ghost.mp3 +C:/Users/Rik/Music/Artists/White Lies/Ritual/White Lies - Is Love.mp3 +C:/Users/Rik/Music/Artists/White Lies/Ritual/White Lies - Peace & Quiet.mp3 +C:/Users/Rik/Music/Artists/White Lies/Ritual/White Lies - Strangers.mp3 +C:/Users/Rik/Music/Artists/White Lies/Ritual/White Lies - Streetlights.mp3 +C:/Users/Rik/Music/Artists/White Lies/Ritual/White Lies - The Power & The Glory.mp3 +C:/Users/Rik/Music/Artists/White Lies/Ritual/White Lies - Turn The Bells.mp3 +C:/Users/Rik/Music/Artists/Destine/Destine - Thousand Miles.mp3 +C:/Users/Rik/Music/Artists/The Seer/Heading for the Sun/The Seer - Dive Into The Blue Sky.mp3 +C:/Users/Rik/Music/Artists/The Seer/Heading for the Sun/The Seer - Eyes Gone Blind.mp3 +C:/Users/Rik/Music/Artists/The Seer/Heading for the Sun/The Seer - Fallen Leaves.mp3 +C:/Users/Rik/Music/Artists/The Seer/Heading for the Sun/The Seer - Rain Down On Me.mp3 +C:/Users/Rik/Music/Artists/The Seer/Heading for the Sun/The Seer - Raining.mp3 +C:/Users/Rik/Music/Artists/The Seer/Heading for the Sun/The Seer - Setting Sails.mp3 +C:/Users/Rik/Music/Artists/The Seer/Heading for the Sun/The Seer - The Borderline.mp3 +C:/Users/Rik/Music/Artists/The Seer/Heading for the Sun/The Seer - The Enemy.mp3 +C:/Users/Rik/Music/Artists/The Seer/Heading for the Sun/The Seer - Wasted.mp3 +C:/Users/Rik/Music/Artists/The Seer/Heading for the Sun/The Seer - What We Are.mp3 +C:/Users/Rik/Music/Artists/The Seer/Heading for the Sun/The Seer - Where Do We Go.mp3 +C:/Users/Rik/Music/Artists/The Seer/Heading for the Sun/The Seer - Wishful Thinking.mp3 +C:/Users/Rik/Music/Old/Bruce Springsteen/Bruce Springsteen - The River.mp3 +C:/Users/Rik/Music/Archive/Artists/Snow Patrol/Fallen Empires/Snow Patrol - Called Out In The Dark.mp3 +C:/Users/Rik/Music/Archive/Artists/Snow Patrol/Fallen Empires/Snow Patrol - This Isn't Everything You Are.mp3 +C:/Users/Rik/Music/Archive/Artists/The Wombats/This Modern Glitch/The Wombats - Techno Fan.mp3 +C:/Users/Rik/Music/Archive/Artists/The Wombats/This Modern Glitch/The Wombats - Tokyo (Vampires & Wolves).mp3 +C:/Users/Rik/Music/Artists/The Offspring/Rise and Fall Rage and Grace/The Offspring - A Lot Like Me.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Rise and Fall Rage and Grace/The Offspring - Fix You.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Rise and Fall Rage and Grace/The Offspring - Half-Truism.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Rise and Fall Rage and Grace/The Offspring - Hammerhead.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Rise and Fall Rage and Grace/The Offspring - Kristy, Are You Doing Okay.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Rise and Fall Rage and Grace/The Offspring - Let's Hear It For Rock Bottom.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Rise and Fall Rage and Grace/The Offspring - Nothingtown.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Rise and Fall Rage and Grace/The Offspring - O.C. Life.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Rise and Fall Rage and Grace/The Offspring - Rise And Fall.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Rise and Fall Rage and Grace/The Offspring - Stuff Is Messed Up.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Rise and Fall Rage and Grace/The Offspring - Takes Me Nowhere.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Rise and Fall Rage and Grace/The Offspring - Trust In You.mp3 +C:/Users/Rik/Music/Artists/The Offspring/Rise and Fall Rage and Grace/The Offspring - You're Gonna Go Far, Kid.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Here and Now/Nickelback - Bottoms Up.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Here and Now/Nickelback - Don't Ever Let It End.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Here and Now/Nickelback - Everything I Wanna Do.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Here and Now/Nickelback - Gotta Get Me Some.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Here and Now/Nickelback - Holding On to Heaven.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Here and Now/Nickelback - Kiss It Goodbye.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Here and Now/Nickelback - Lullaby.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Here and Now/Nickelback - Midnight Queen.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Here and Now/Nickelback - This Means War.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Here and Now/Nickelback - Trying Not to Love You.mp3 +C:/Users/Rik/Music/Artists/Nickelback/Here and Now/Nickelback - When We Stand Together.mp3 +C:/Users/Rik/Music/Artists/The Vaccines/What Did You Expect From The Vaccines/The Vaccines - A Lack of Understanding.mp3 +C:/Users/Rik/Music/Artists/The Vaccines/What Did You Expect From The Vaccines/The Vaccines - All in White.mp3 +C:/Users/Rik/Music/Artists/The Vaccines/What Did You Expect From The Vaccines/The Vaccines - Blow It Up.mp3 +C:/Users/Rik/Music/Artists/The Vaccines/What Did You Expect From The Vaccines/The Vaccines - Family Friend.mp3 +C:/Users/Rik/Music/Artists/The Vaccines/What Did You Expect From The Vaccines/The Vaccines - If You Wanna.mp3 +C:/Users/Rik/Music/Artists/The Vaccines/What Did You Expect From The Vaccines/The Vaccines - N%C3%B8rgaard.mp3 +C:/Users/Rik/Music/Artists/The Vaccines/What Did You Expect From The Vaccines/The Vaccines - Post Break-Up Sex.mp3 +C:/Users/Rik/Music/Artists/The Vaccines/What Did You Expect From The Vaccines/The Vaccines - Under Your Thumb.mp3 +C:/Users/Rik/Music/Artists/The Vaccines/What Did You Expect From The Vaccines/The Vaccines - Westsuit.mp3 +C:/Users/Rik/Music/Artists/The Vaccines/What Did You Expect From The Vaccines/The Vaccines - Wolf Pack.mp3 +C:/Users/Rik/Music/Artists/The Vaccines/What Did You Expect From The Vaccines/The Vaccines - Wreckin' Bar.mp3 +C:/Users/Rik/Music/Artists/Daughtry/Leave This Town/Daughtry - Call Your Name.mp3 +C:/Users/Rik/Music/Artists/Daughtry/Leave This Town/Daughtry - Every Time You Turn Around.mp3 +C:/Users/Rik/Music/Artists/Daughtry/Leave This Town/Daughtry - Ghost Of Me.mp3 +C:/Users/Rik/Music/Artists/Daughtry/Leave This Town/Daughtry - Learn My Lesson.mp3 +C:/Users/Rik/Music/Artists/Daughtry/Leave This Town/Daughtry - Life After You.mp3 +C:/Users/Rik/Music/Artists/Daughtry/Leave This Town/Daughtry - No Surprise.mp3 +C:/Users/Rik/Music/Artists/Daughtry/Leave This Town/Daughtry - Open Up Your Eyes.mp3 +C:/Users/Rik/Music/Artists/Daughtry/Leave This Town/Daughtry - September.mp3 +C:/Users/Rik/Music/Artists/Daughtry/Leave This Town/Daughtry - Supernatural.mp3 +C:/Users/Rik/Music/Artists/Daughtry/Leave This Town/Daughtry - Tennessee Line.mp3 +C:/Users/Rik/Music/Artists/Daughtry/Leave This Town/Daughtry - What I Meant To Say.mp3 +C:/Users/Rik/Music/Artists/Daughtry/Leave This Town/Daughtry - You Don't Belong.mp3 +C:/Users/Rik/Music/Artists/Moke/The Long & Dangerous Sea/Moke - Black And Blue.mp3 +C:/Users/Rik/Music/Artists/Moke/The Long & Dangerous Sea/Moke - Ghost.mp3 +C:/Users/Rik/Music/Artists/Moke/The Long & Dangerous Sea/Moke - Heaven.mp3 +C:/Users/Rik/Music/Artists/Moke/The Long & Dangerous Sea/Moke - Lament.mp3 +C:/Users/Rik/Music/Artists/Moke/The Long & Dangerous Sea/Moke - Love My Life.mp3 +C:/Users/Rik/Music/Artists/Moke/The Long & Dangerous Sea/Moke - Nobody's Listening.mp3 +C:/Users/Rik/Music/Artists/Moke/The Long & Dangerous Sea/Moke - Switch.mp3 +C:/Users/Rik/Music/Artists/Moke/The Long & Dangerous Sea/Moke - Terrible End.mp3 +C:/Users/Rik/Music/Artists/Moke/The Long & Dangerous Sea/Moke - The Long & Dangerous Sea.mp3 +C:/Users/Rik/Music/Artists/Moke/The Long & Dangerous Sea/Moke - Windows Of Hope.mp3 +C:/Users/Rik/Music/Artists/Placebo/Battle for the Sun/Placebo - Ashtray Heart.mp3 +C:/Users/Rik/Music/Artists/Placebo/Battle for the Sun/Placebo - Battle for the Sun.mp3 +C:/Users/Rik/Music/Artists/Placebo/Battle for the Sun/Placebo - Breathe Underwater.mp3 +C:/Users/Rik/Music/Artists/Placebo/Battle for the Sun/Placebo - Bright Lights.mp3 +C:/Users/Rik/Music/Artists/Placebo/Battle for the Sun/Placebo - Come Undone.mp3 +C:/Users/Rik/Music/Artists/Placebo/Battle for the Sun/Placebo - Devil in the Details.mp3 +C:/Users/Rik/Music/Artists/Placebo/Battle for the Sun/Placebo - For What It's Worth.mp3 +C:/Users/Rik/Music/Artists/Placebo/Battle for the Sun/Placebo - Happy You're Gone.mp3 +C:/Users/Rik/Music/Artists/Placebo/Battle for the Sun/Placebo - Julien.mp3 +C:/Users/Rik/Music/Artists/Placebo/Battle for the Sun/Placebo - Kings of Medicine.mp3 +C:/Users/Rik/Music/Artists/Placebo/Battle for the Sun/Placebo - Kitty Litter.mp3 +C:/Users/Rik/Music/Artists/Placebo/Battle for the Sun/Placebo - Speak in Tongues.mp3 +C:/Users/Rik/Music/Artists/Placebo/Battle for the Sun/Placebo - The Never-Ending Why.mp3 +C:/Users/Rik/Music/Artists/Keane/Night Train/Keane - Back In Time.mp3 +C:/Users/Rik/Music/Artists/Keane/Night Train/Keane - Clear Skies.mp3 +C:/Users/Rik/Music/Artists/Keane/Night Train/Keane - House Lights.mp3 +C:/Users/Rik/Music/Artists/Keane/Night Train/Keane - Ishin Denshin (You've Got To Help Yourself).mp3 +C:/Users/Rik/Music/Artists/Keane/Night Train/Keane - Looking Back.mp3 +C:/Users/Rik/Music/Artists/Keane/Night Train/Keane - My Shadow.mp3 +C:/Users/Rik/Music/Artists/Keane/Night Train/Keane - Stop For a Minute.mp3 +C:/Users/Rik/Music/Artists/Keane/Night Train/Keane - Your Love.mp3 +C:/Users/Rik/Music/Artists/Keane/Under The Iron Sea/Keane - A Bad Dream.mp3 +C:/Users/Rik/Music/Artists/Keane/Under The Iron Sea/Keane - Atlantic.mp3 +C:/Users/Rik/Music/Artists/Keane/Under The Iron Sea/Keane - Broken Toy.mp3 +C:/Users/Rik/Music/Artists/Keane/Under The Iron Sea/Keane - Crystal Ball.mp3 +C:/Users/Rik/Music/Artists/Keane/Under The Iron Sea/Keane - Hamburg Song.mp3 +C:/Users/Rik/Music/Artists/Keane/Under The Iron Sea/Keane - Is It Any Wonder.mp3 +C:/Users/Rik/Music/Artists/Keane/Under The Iron Sea/Keane - Leaving So Soon.mp3 +C:/Users/Rik/Music/Artists/Keane/Under The Iron Sea/Keane - Let It Slide .mp3 +C:/Users/Rik/Music/Artists/Keane/Under The Iron Sea/Keane - Nothing In My Way.mp3 +C:/Users/Rik/Music/Artists/Keane/Under The Iron Sea/Keane - Put It Behind You.mp3 +C:/Users/Rik/Music/Artists/Keane/Under The Iron Sea/Keane - The Frog Prince.mp3 +C:/Users/Rik/Music/Artists/Keane/Under The Iron Sea/Keane - The Iron Sea.mp3 +C:/Users/Rik/Music/Artists/Keane/Under The Iron Sea/Keane - Try Again.mp3 +C:/Users/Rik/Music/Artists/Hey Monday/Hold On Tight/Hey Monday - 6 Months.mp3 +C:/Users/Rik/Music/Artists/Hey Monday/Hold On Tight/Hey Monday - Arizona.mp3 +C:/Users/Rik/Music/Artists/Hey Monday/Hold On Tight/Hey Monday - Candles.mp3 +C:/Users/Rik/Music/Artists/Hey Monday/Hold On Tight/Hey Monday - Homecoming.mp3 +C:/Users/Rik/Music/Artists/Hey Monday/Hold On Tight/Hey Monday - How You Love Me Now.mp3 +C:/Users/Rik/Music/Artists/Hey Monday/Hold On Tight/Hey Monday - Hurricane Streets.mp3 +C:/Users/Rik/Music/Artists/Hey Monday/Hold On Tight/Hey Monday - Josey.mp3 +C:/Users/Rik/Music/Artists/Hey Monday/Hold On Tight/Hey Monday - Obvious.mp3 +C:/Users/Rik/Music/Artists/Hey Monday/Hold On Tight/Hey Monday - Run, Don't Walk.mp3 +C:/Users/Rik/Music/Artists/Hey Monday/Hold On Tight/Hey Monday - Set Off.mp3 +C:/Users/Rik/Music/Artists/Hey Monday/Hold On Tight/Hey Monday - Should've Tried Harder.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - Anything.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - Breakdown.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - Cover Me.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - Epilogue.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - Mistakes we Knew we Were Making.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - Painless.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - Prologue.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - Ready and Waiting to Fall.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - Someone Else's Arms.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - Suspension.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - The Everglow.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - The Ocean.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - The Sun and the Moon.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - This is the Countdown.mp3 +C:/Users/Rik/Music/Artists/Mae/The Everglow/Mae - We're So Far Away.mp3 +C:/Users/Rik/Music/Artists/Saves the Day/Saves the Day - All I'm Losing Is Me.mp3 +C:/Users/Rik/Music/Artists/Saves the Day/Saves the Day - At Your Funeral.mp3 +C:/Users/Rik/Music/Artists/Saves the Day/Saves the Day - Cars And Calories.mp3 +C:/Users/Rik/Music/Artists/Saves the Day/Saves the Day - Certain Tragedy.mp3 +C:/Users/Rik/Music/Artists/Saves the Day/Saves the Day - Firefly.mp3 +C:/Users/Rik/Music/Artists/Saves the Day/Saves the Day - Freakish.mp3 +C:/Users/Rik/Music/Artists/Saves the Day/Saves the Day - Jukebox Breakdown.mp3 +C:/Users/Rik/Music/Artists/Saves the Day/Saves the Day - Nightingale.mp3 +C:/Users/Rik/Music/Artists/Saves the Day/Saves the Day - See You.mp3 +C:/Users/Rik/Music/Artists/Saves the Day/Saves the Day - This Is Not An Exit.mp3 +C:/Users/Rik/Music/Artists/Saves the Day/Saves the Day - Your Ghost Takes Flight.mp3 \ No newline at end of file diff --git a/java/sound/txt/options b/java/sound/txt/options new file mode 100644 index 0000000..4d95aae --- /dev/null +++ b/java/sound/txt/options @@ -0,0 +1,182 @@ +LAME 32bits version 3.98.4 (http://www.mp3dev.org/) + +usage: lame [options] [outfile] + + and/or can be "-", which means stdin/stdout. + +RECOMMENDED: + lame -V2 input.wav output.mp3 + +OPTIONS: + Input options: + --scale scale input (multiply PCM data) by + --scale-l scale channel 0 (left) input (multiply PCM data) by + --scale-r scale channel 1 (right) input (multiply PCM data) by + --mp1input input file is a MPEG Layer I file + --mp2input input file is a MPEG Layer II file + --mp3input input file is a MPEG Layer III file + --nogap <...> + gapless encoding for a set of contiguous files + --nogapout + output dir for gapless encoding (must precede --nogap) + --nogaptags allow the use of VBR tags in gapless encoding + + Input options for RAW PCM: + -r input is raw pcm + -x force byte-swapping of input + -s sfreq sampling frequency of input file (kHz) - default 44.1 kHz + --bitwidth w input bit width is w (default 16) + --signed input is signed (default) + --unsigned input is unsigned + --little-endian input is little-endian (default) + --big-endian input is big-endian + + + Operational options: + -a downmix from stereo to mono file for mono encoding + -m (j)oint, (s)imple, (f)orce, (d)dual-mono, (m)ono + default is (j) or (s) depending on bitrate + joint = joins the best possible of MS and LR stereo + simple = force LR stereo on all frames + force = force MS stereo on all frames. + --preset type type must be "medium", "standard", "extreme", "insane", + or a value for an average desired bitrate and depending + on the value specified, appropriate quality settings will + be used. + "--preset help" gives more info on these + --comp choose bitrate to achive a compression ratio of + --replaygain-fast compute RG fast but slightly inaccurately (default) + --replaygain-accurate compute RG more accurately and find the peak sample + --noreplaygain disable ReplayGain analysis + --clipdetect enable --replaygain-accurate and print a message whether + clipping occurs and how far the waveform is from full scale + --flush flush output stream as soon as possible + --freeformat produce a free format bitstream + --decode input=mp3 file, output=wav + -t disable writing wav header when using --decode + + + Verbosity: + --disptime print progress report every arg seconds + -S don't print progress report, VBR histograms + --nohist disable VBR histogram display + --silent don't print anything on screen + --quiet don't print anything on screen + --brief print more useful information + --verbose print a lot of useful information + + Noise shaping & psycho acoustic algorithms: + -q = 0...9. Default -q 5 + -q 0: Highest quality, very slow + -q 9: Poor quality, but fast + -h Same as -q 2. Recommended. + -f Same as -q 7. Fast, ok quality + + + CBR (constant bitrate, the default) options: + -b set the bitrate in kbps, default 128 kbps + --cbr enforce use of constant bitrate + + ABR options: + --abr specify average bitrate desired (instead of quality) + + VBR options: + -V n quality setting for VBR. default n=4 + 0=high quality,bigger files. 9=smaller files + -v the same as -V 4 + --vbr-old use old variable bitrate (VBR) routine + --vbr-new use new variable bitrate (VBR) routine (default) + -b specify minimum allowed bitrate, default 32 kbps + -B specify maximum allowed bitrate, default 320 kbps + -F strictly enforce the -b option, for use with players that + do not support low bitrate mp3 + -t disable writing LAME Tag + -T enable and force writing LAME Tag + + + PSY related: + --temporal-masking x x=0 disables, x=1 enables temporal masking effect + --nssafejoint M/S switching criterion + --nsmsfix M/S switching tuning [effective 0-3.5] + --interch x adjust inter-channel masking ratio + --ns-bass x adjust masking for sfbs 0 - 6 (long) 0 - 5 (short) + --ns-alto x adjust masking for sfbs 7 - 13 (long) 6 - 10 (short) + --ns-treble x adjust masking for sfbs 14 - 21 (long) 11 - 12 (short) + --ns-sfb21 x change ns-treble by x dB for sfb21 + + + experimental switches: + -Y lets LAME ignore noise in sfb21, like in CBR + + + MP3 header/stream options: + -e de-emphasis n/5/c (obsolete) + -c mark as copyright + -o mark as non-original + -p error protection. adds 16 bit checksum to every frame + (the checksum is computed correctly) + --nores disable the bit reservoir + --strictly-enforce-ISO comply as much as possible to ISO MPEG spec + + Filter options: + --lowpass frequency(kHz), lowpass filter cutoff above freq + --lowpass-width frequency(kHz) - default 15% of lowpass freq + --highpass frequency(kHz), highpass filter cutoff below freq + --highpass-width frequency(kHz) - default 15% of highpass freq + --resample sampling frequency of output file(kHz)- default=automatic + + + ID3 tag options: + --tt audio/song title (max 30 chars for version 1 tag) + --ta <artist> audio/song artist (max 30 chars for version 1 tag) + --tl <album> audio/song album (max 30 chars for version 1 tag) + --ty <year> audio/song year of issue (1 to 9999) + --tc <comment> user-defined text (max 30 chars for v1 tag, 28 for v1.1) + --tn <track[/total]> audio/song track number and (optionally) the total + number of tracks on the original recording. (track + and total each 1 to 255. just the track number + creates v1.1 tag, providing a total forces v2.0). + --tg <genre> audio/song genre (name or number in list) + --ti <file> audio/song albumArt (jpeg/png/gif file, 128KB max, v2.3) + --tv <id=value> user-defined frame specified by id and value (v2.3 tag) + --add-id3v2 force addition of version 2 tag + --id3v1-only add only a version 1 tag + --id3v2-only add only a version 2 tag + --space-id3v1 pad version 1 tag with spaces instead of nulls + --pad-id3v2 same as '--pad-id3v2-size 128' + --pad-id3v2-size <value> adds version 2 tag, pad with extra <value> bytes + --genre-list print alphabetically sorted ID3 genre list and exit + --ignore-tag-errors ignore errors in values passed for tags + + Note: A version 2 tag will NOT be added unless one of the input fields + won't fit in a version 1 tag (e.g. the title string is longer than 30 + characters), or the '--add-id3v2' or '--id3v2-only' options are used, + or output is redirected to stdout. + + +MS-Windows-specific options: + --priority <type> sets the process priority: + 0,1 = Low priority (IDLE_PRIORITY_CLASS) + 2 = normal priority (NORMAL_PRIORITY_CLASS, default) + 3,4 = High priority (HIGH_PRIORITY_CLASS)) + Note: Calling '--priority' without a parameter will select priority 0. + +Misc: + --license print License information + + + + Platform specific: + --noasm <instructions> disable assembly optimizations for mmx/3dnow/sse + + + +MPEG-1 layer III sample frequencies (kHz): 32 48 44.1 +bitrates (kbps): 32 40 48 56 64 80 96 112 128 160 192 224 256 320 + +MPEG-2 layer III sample frequencies (kHz): 16 24 22.05 +bitrates (kbps): 8 16 24 32 40 48 56 64 80 96 112 128 144 160 + +MPEG-2.5 layer III sample frequencies (kHz): 8 12 11.025 +bitrates (kbps): 8 16 24 32 40 48 56 64 + diff --git a/java/sound/txt/short b/java/sound/txt/short new file mode 100644 index 0000000..538d3ff --- /dev/null +++ b/java/sound/txt/short @@ -0,0 +1 @@ +medium.mp3 \ No newline at end of file diff --git a/java/sound/txt/testfiles.txt b/java/sound/txt/testfiles.txt new file mode 100644 index 0000000..6c2c2b6 --- /dev/null +++ b/java/sound/txt/testfiles.txt @@ -0,0 +1,12 @@ +junk (with or without header) +PCM_SIGNED 8000.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian +-r 8k -t s16 -c 1 -e signed-integer + + +out (without header) +PCM_SIGNED 8000.0 Hz, 16 bit, stereo, 4 bytes/frame, big-endian +-r 128k -t s32 -c 2 -2 signed integer [reasonable] + +out (without header) +PCM_SIGNED 192000.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian +-r 192k -t s16 -c 2 [-e signed-integer] \ No newline at end of file diff --git a/java/sound/wget.exe b/java/sound/wget.exe new file mode 100644 index 0000000..f2a11c1 Binary files /dev/null and b/java/sound/wget.exe differ diff --git a/java/sound/zlib1.dll b/java/sound/zlib1.dll new file mode 100644 index 0000000..89c8002 Binary files /dev/null and b/java/sound/zlib1.dll differ