[UNIATA] Update to v0.46e1. CORE-11451

svn path=/trunk/; revision=73324
This commit is contained in:
Amine Khaldi 2016-11-20 15:58:03 +00:00
parent c5ad9e290c
commit d14a8724c0
9 changed files with 146 additions and 63 deletions

View file

@ -1,5 +1,5 @@
// Build Version 0.46d7 // Build Version 0.46d8
UCHAR const AtaCommands48[256] = { UCHAR const AtaCommands48[256] = {

View file

@ -1302,7 +1302,8 @@ IdeMediaStatus(
IN ULONG DeviceNumber IN ULONG DeviceNumber
); );
ULONG NTAPI ULONG
NTAPI
AtapiFindIsaController( AtapiFindIsaController(
IN PVOID HwDeviceExtension, IN PVOID HwDeviceExtension,
IN PVOID Context, IN PVOID Context,
@ -1312,6 +1313,17 @@ AtapiFindIsaController(
OUT PBOOLEAN Again OUT PBOOLEAN Again
); );
ULONG
NTAPI
AtapiReadArgumentString(
IN PVOID HwDeviceExtension,
IN PVOID Context,
IN PVOID BusInformation,
IN PCHAR ArgumentString,
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
OUT PBOOLEAN Again
);
ULONG ULONG
NTAPI NTAPI
AtapiParseArgumentString( AtapiParseArgumentString(

View file

@ -553,4 +553,4 @@ BUSMASTER_CONTROLLER_INFORMATION_BASE const BusMasterAdapters[] = {
PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, BMLIST_TERMINATOR, NULL , BMLIST_TERMINATOR ) PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, BMLIST_TERMINATOR, NULL , BMLIST_TERMINATOR )
}; };
const ULONG _NUM_BUSMASTER_ADAPTERS = (sizeof(BusMasterAdapters) / sizeof(BUSMASTER_CONTROLLER_INFORMATION_BASE)); /* static */ const ULONG _NUM_BUSMASTER_ADAPTERS = (sizeof(BusMasterAdapters) / sizeof(BUSMASTER_CONTROLLER_INFORMATION_BASE));

View file

@ -1881,6 +1881,7 @@ extern BOOLEAN g_opt_AtapiDmaRawRead;
extern BOOLEAN hasPCI; extern BOOLEAN hasPCI;
extern BOOLEAN InDriverEntry; extern BOOLEAN InDriverEntry;
extern BOOLEAN g_Dump;
extern BOOLEAN g_opt_Verbose; extern BOOLEAN g_opt_Verbose;
extern ULONG g_opt_VirtualMachine; extern ULONG g_opt_VirtualMachine;

View file

@ -105,6 +105,7 @@ BOOLEAN hasPCI = FALSE;
ULONG g_opt_VirtualMachine = 0; // Auto ULONG g_opt_VirtualMachine = 0; // Auto
BOOLEAN InDriverEntry = TRUE; BOOLEAN InDriverEntry = TRUE;
BOOLEAN g_Dump = FALSE;
BOOLEAN g_opt_Verbose = 0; BOOLEAN g_opt_Verbose = 0;
@ -5036,7 +5037,7 @@ AtapiInterrupt__(
return TRUE; return TRUE;
} }
if(!DmaTransfer && !atapiDev) { if((!DmaTransfer && !atapiDev) || deviceExtension->DriverMustPoll) {
KdPrint2((PRINT_PREFIX " service PIO HDD\n")); KdPrint2((PRINT_PREFIX " service PIO HDD\n"));
UseDpc = FALSE; UseDpc = FALSE;
} }
@ -6139,7 +6140,9 @@ CompleteRequest:
} else { // srb->Cdb[0] == SCSIOP_REQUEST_SENSE) } else { // srb->Cdb[0] == SCSIOP_REQUEST_SENSE)
PSENSE_DATA senseData = (PSENSE_DATA) srb->DataBuffer; PSENSE_DATA senseData = (PSENSE_DATA) srb->DataBuffer;
#ifdef __REACTOS__
(void)senseData; (void)senseData;
#endif
KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI command status %#x\n", status)); KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI command status %#x\n", status));
if (status == SRB_STATUS_DATA_OVERRUN) { if (status == SRB_STATUS_DATA_OVERRUN) {
// Check to see if we at least get mininum number of bytes // Check to see if we at least get mininum number of bytes
@ -10516,16 +10519,56 @@ DriverEntry(
LARGE_INTEGER t0, t1; LARGE_INTEGER t0, t1;
Connect_DbgPrint();
KdPrint2((PRINT_PREFIX "%s", (PCCHAR)ver_string)); KdPrint2((PRINT_PREFIX "%s", (PCCHAR)ver_string));
//a = (WCHAR)strlen(ver_string); //a = (WCHAR)strlen(ver_string);
g_opt_Verbose = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PrintLogo", 0); statusToReturn = 0xffffffff;
if(g_opt_Verbose) {
_PrintNtConsole("Universal ATA driver v 0." UNIATA_VER_STR "\n"); // Zero out structure.
RtlZeroMemory(((PCHAR)&hwInitializationData), sizeof(hwInitializationData));
// Set size of hwInitializationData.
hwInitializationData.comm.HwInitializationDataSize =
sizeof(hwInitializationData.comm) +
// sizeof(hwInitializationData.nt4) +
((WinVer_Id() <= WinVer_NT) ? 0 : sizeof(hwInitializationData.w2k));
KdPrint(("HwInitializationDataSize = %x\n", hwInitializationData.comm.HwInitializationDataSize));
// Set entry points.
hwInitializationData.comm.HwInitialize = (PHW_INITIALIZE)AtapiHwInitialize;
hwInitializationData.comm.HwResetBus = (PHW_RESET_BUS)AtapiResetController;
hwInitializationData.comm.HwStartIo = (PHW_STARTIO)AtapiStartIo;
hwInitializationData.comm.HwInterrupt = (PHW_INTERRUPT)AtapiInterrupt;
// Specify size of extensions.
hwInitializationData.comm.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
hwInitializationData.comm.SpecificLuExtensionSize = sizeof(HW_LU_EXTENSION);
hwInitializationData.comm.SrbExtensionSize = sizeof(ATA_REQ);
// Indicate PIO device.
hwInitializationData.comm.MapBuffers = TRUE;
// Request and parse arument string.
KdPrint2((PRINT_PREFIX "\n\nUniATA: parse ArgumentString\n"));
// Zero out structure.
hwInitializationData.comm.NumberOfAccessRanges = 2;
hwInitializationData.comm.HwFindAdapter = AtapiReadArgumentString;
ScsiPortInitialize(DriverObject,
Argument2,
&hwInitializationData.comm,
&adapterCount);
if(!g_Dump) {
Connect_DbgPrint();
g_opt_Verbose = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PrintLogo", 0);
if(g_opt_Verbose) {
_PrintNtConsole("Universal ATA driver v 0." UNIATA_VER_STR "\n");
}
IgnoreIsaCompatiblePci = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreIsaCompatiblePci", IgnoreIsaCompatiblePci) ? TRUE : FALSE;
IgnoreNativePci = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreNativePci", IgnoreNativePci) ? TRUE : FALSE;
} else {
KdPrint(("crashdump mode\n"));
} }
IgnoreIsaCompatiblePci = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreIsaCompatiblePci", IgnoreIsaCompatiblePci) ? TRUE : FALSE;
IgnoreNativePci = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreNativePci", IgnoreNativePci) ? TRUE : FALSE;
if(!SavedDriverObject) { if(!SavedDriverObject) {
SavedDriverObject = (PDRIVER_OBJECT)DriverObject; SavedDriverObject = (PDRIVER_OBJECT)DriverObject;
@ -10597,31 +10640,6 @@ DriverEntry(
g_LogToDisplay = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"LogToDisplay", 0); g_LogToDisplay = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"LogToDisplay", 0);
#endif //_DEBUG #endif //_DEBUG
statusToReturn = 0xffffffff;
// Zero out structure.
RtlZeroMemory(((PCHAR)&hwInitializationData), sizeof(hwInitializationData));
// Set size of hwInitializationData.
hwInitializationData.comm.HwInitializationDataSize =
sizeof(hwInitializationData.comm) +
// sizeof(hwInitializationData.nt4) +
((WinVer_Id() <= WinVer_NT) ? 0 : sizeof(hwInitializationData.w2k));
KdPrint(("HwInitializationDataSize = %x\n", hwInitializationData.comm.HwInitializationDataSize));
// Set entry points.
hwInitializationData.comm.HwInitialize = (PHW_INITIALIZE)AtapiHwInitialize;
hwInitializationData.comm.HwResetBus = (PHW_RESET_BUS)AtapiResetController;
hwInitializationData.comm.HwStartIo = (PHW_STARTIO)AtapiStartIo;
hwInitializationData.comm.HwInterrupt = (PHW_INTERRUPT)AtapiInterrupt;
// Specify size of extensions.
hwInitializationData.comm.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
hwInitializationData.comm.SpecificLuExtensionSize = sizeof(HW_LU_EXTENSION);
hwInitializationData.comm.SrbExtensionSize = sizeof(ATA_REQ);
// Indicate PIO device.
hwInitializationData.comm.MapBuffers = TRUE;
// Set PnP-specific API // Set PnP-specific API
if(WinVer_Id() > WinVer_NT) { if(WinVer_Id() > WinVer_NT) {
KdPrint(("set NeedPhysicalAddresses = TRUE\n")); KdPrint(("set NeedPhysicalAddresses = TRUE\n"));
@ -10723,7 +10741,7 @@ DriverEntry(
SecondaryClaimed = TRUE; SecondaryClaimed = TRUE;
pref_alt = 0; pref_alt = 0;
if(!WinVer_WDM_Model && !PrimaryClaimed && !SecondaryClaimed && if(!WinVer_WDM_Model && !PrimaryClaimed && !SecondaryClaimed && !g_Dump &&
!(BMList[i].ChanInitOk & 0x80)) { !(BMList[i].ChanInitOk & 0x80)) {
// We just want to claim our PCI device in compatible mode, since we shall not // We just want to claim our PCI device in compatible mode, since we shall not
@ -11295,6 +11313,10 @@ AtapiRegCheckParameterValue(
UNICODE_STRING paramPath; UNICODE_STRING paramPath;
if(g_Dump) {
goto failed;
}
// <SavedRegPath>\<PathSuffix> -> <Name> // <SavedRegPath>\<PathSuffix> -> <Name>
// KdPrint(( "AtapiCheckRegValue: %ws -> %ws\n", PathSuffix, Name)); // KdPrint(( "AtapiCheckRegValue: %ws -> %ws\n", PathSuffix, Name));
// KdPrint(( "AtapiCheckRegValue: RegistryPath %ws\n", RegistryPath->Buffer)); // KdPrint(( "AtapiCheckRegValue: RegistryPath %ws\n", RegistryPath->Buffer));
@ -11332,6 +11354,7 @@ AtapiRegCheckParameterValue(
ExFreePool(paramPath.Buffer); ExFreePool(paramPath.Buffer);
if(!NT_SUCCESS(status)) { if(!NT_SUCCESS(status)) {
failed:
doRun = Default; doRun = Default;
} }

View file

@ -1148,14 +1148,14 @@ AtapiDmaInit(
if(ChipType == ATPOLD) { if(ChipType == ATPOLD) {
/* Old Acard 850 */ /* Old Acard 850 */
static const USHORT reg4x = 0x0301; static const USHORT reg4x2 = 0x0301;
for(i=udmamode; i>=0; i--) { for(i=udmamode; i>=0; i--) {
if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA + i)) { if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA + i)) {
set_old_acard: set_old_acard:
ChangePciConfig1(0x54, a | (0x01 << dev) | ((i+1) << (dev*2))); ChangePciConfig1(0x54, a | (0x01 << dev) | ((i+1) << (dev*2)));
SetPciConfig1(0x4a, reg4a); SetPciConfig1(0x4a, reg4a);
SetPciConfig2(reg, reg4x); SetPciConfig2(reg, reg4x2);
return; return;
} }

View file

@ -623,6 +623,7 @@ for_ugly_chips:
} }
if(deviceExtension->MaxTransferMode >= ATA_SA150) { if(deviceExtension->MaxTransferMode >= ATA_SA150) {
KdPrint2((PRINT_PREFIX "setting UNIATA_SATA flag\n"));
deviceExtension->HwFlags |= UNIATA_SATA; deviceExtension->HwFlags |= UNIATA_SATA;
} }
@ -977,13 +978,16 @@ for_ugly_chips:
i = AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION_BASE*)&SiSSouthAdapters[0], i = AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION_BASE*)&SiSSouthAdapters[0],
-1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL); -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL);
if(i != BMLIST_TERMINATOR) { if(i != BMLIST_TERMINATOR) {
KdPrint2((PRINT_PREFIX "SIS South\n"));
deviceExtension->HwFlags = (deviceExtension->HwFlags & ~CHIPTYPE_MASK) | SIS133OLD; deviceExtension->HwFlags = (deviceExtension->HwFlags & ~CHIPTYPE_MASK) | SIS133OLD;
deviceExtension->MaxTransferMode = ATA_UDMA6; deviceExtension->MaxTransferMode = ATA_UDMA6;
//deviceExtension->MaxTransferMode = SiSSouthAdapters[i].MaxTransferMode; //deviceExtension->MaxTransferMode = SiSSouthAdapters[i].MaxTransferMode;
if(SiSSouthAdapters[i].RaidFlags & UNIATA_SATA) { if(SiSSouthAdapters[i].RaidFlags & UNIATA_SATA) {
KdPrint2((PRINT_PREFIX "SIS South SATA\n"));
deviceExtension->HwFlags |= UNIATA_SATA; deviceExtension->HwFlags |= UNIATA_SATA;
if(SiSSouthAdapters[i].nDeviceId == 0x1182 || if(SiSSouthAdapters[i].nDeviceId == 0x1182 ||
SiSSouthAdapters[i].nDeviceId == 0x1183) { SiSSouthAdapters[i].nDeviceId == 0x1183) {
KdPrint2((PRINT_PREFIX "SIS_182\n"));
SIS_182 = TRUE; SIS_182 = TRUE;
} }
} }

View file

@ -1256,6 +1256,14 @@ UniataFindBusMasterController(
/***********************************************************/ /***********************************************************/
deviceExtension->UseDpc = TRUE; deviceExtension->UseDpc = TRUE;
#ifndef UNIATA_CORE
if (g_Dump) {
deviceExtension->DriverMustPoll = TRUE;
deviceExtension->UseDpc = FALSE;
deviceExtension->simplexOnly = TRUE;
deviceExtension->HwFlags |= UNIATA_NO_DPC;
}
#endif //UNIATA_CORE
KdPrint2((PRINT_PREFIX "HwFlags = %x\n (3)", deviceExtension->HwFlags)); KdPrint2((PRINT_PREFIX "HwFlags = %x\n (3)", deviceExtension->HwFlags));
if(deviceExtension->HwFlags & UNIATA_NO_DPC) { if(deviceExtension->HwFlags & UNIATA_NO_DPC) {
/* CMD 649, ROSB SWK33, ICH4 */ /* CMD 649, ROSB SWK33, ICH4 */
@ -2036,10 +2044,21 @@ UniataConnectIntr2(
KdPrint2((PRINT_PREFIX "Init ISR:\n")); KdPrint2((PRINT_PREFIX "Init ISR:\n"));
/*
We MUST register 2nd ISR for multichannel controllers even for UP systems.
This is needed for cases when
multichannel controller generate interrupt while we are still in its ISR for
other channle's interrupt. New interrupt must be detected and queued for
further processing. If we do not do this, system will not route this
interrupt to main ISR (since it is busy) and we shall get to infinite loop
looking for interrupt handler.
*/
if(!deviceExtension->MasterDev && (deviceExtension->NumberChannels > 1) && // do not touch MasterDev if(!deviceExtension->MasterDev && (deviceExtension->NumberChannels > 1) && // do not touch MasterDev
!deviceExtension->simplexOnly && /* // this is unnecessary on simplex controllers !deviceExtension->simplexOnly && /* // this is unnecessary on simplex controllers
!BMList[i].Isr2DevObj*/ // handle re-init under w2k+ !BMList[i].Isr2DevObj*/ // handle re-init under w2k+
/*!ForceSimplex*/ /*!ForceSimplex*/
/*(CPU_num > 1) && // unnecessary for UP systems*/
TRUE) { TRUE) {
// Ok, continue... // Ok, continue...
KdPrint2((PRINT_PREFIX "Multichannel native mode, go...\n")); KdPrint2((PRINT_PREFIX "Multichannel native mode, go...\n"));
@ -2340,14 +2359,23 @@ AtapiFindIsaController(
// if not, we go and find ourselves // if not, we go and find ourselves
if (preConfig == FALSE) { if (preConfig == FALSE) {
ULONG portBase_reg = 0;
ULONG irq_reg = 0;
if (!portBase) { if (!portBase) {
portBase = AdapterAddresses[*adapterCount]; portBase = AdapterAddresses[*adapterCount];
KdPrint2((PRINT_PREFIX "portBase[%d]=%x\n", *adapterCount, portBase)); KdPrint2((PRINT_PREFIX "portBase[%d]=%x\n", *adapterCount, portBase));
} else { } else {
KdPrint2((PRINT_PREFIX "portBase=%x\n", portBase)); KdPrint2((PRINT_PREFIX "portBase=%x\n", portBase));
} }
portBase = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PortBase", portBase);
irq = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Irq", irq); portBase_reg = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PortBase", 0);
irq_reg = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Irq", 0);
if(portBase_reg && irq_reg) {
KdPrint2((PRINT_PREFIX "use registry settings portBase=%x, irq=%d\n", portBase_reg, irq_reg));
portBase = portBase_reg;
irq = irq_reg;
}
// check if Primary/Secondary Master IDE claimed // check if Primary/Secondary Master IDE claimed
if(AtapiCheckIOInterference(ConfigInfo, portBase)) { if(AtapiCheckIOInterference(ConfigInfo, portBase)) {
goto next_adapter; goto next_adapter;
@ -2587,26 +2615,11 @@ retryIdentifier:
// Determine whether this driver is being initialized by the // Determine whether this driver is being initialized by the
// system or as a crash dump driver. // system or as a crash dump driver.
if (ArgumentString) { if (g_Dump) {
#ifndef UNIATA_CORE #ifndef UNIATA_CORE
if (AtapiParseArgumentString(ArgumentString, "dump") == 1) { deviceExtension->DriverMustPoll = TRUE;
KdPrint2((PRINT_PREFIX
"AtapiFindIsaController: Crash dump\n"));
//atapiOnly = FALSE;
deviceExtension->DriverMustPoll = TRUE;
} else {
KdPrint2((PRINT_PREFIX
"AtapiFindIsaController: Atapi Only\n"));
//atapiOnly = TRUE;
deviceExtension->DriverMustPoll = FALSE;
}
#endif //UNIATA_CORE #endif //UNIATA_CORE
} else { } else {
KdPrint2((PRINT_PREFIX
"AtapiFindIsaController: Atapi Only (2)\n"));
//atapiOnly = TRUE;
deviceExtension->DriverMustPoll = FALSE; deviceExtension->DriverMustPoll = FALSE;
} }
@ -2690,6 +2703,8 @@ not_found:
(*ConfigInfo->AccessRanges)[i].RangeLength = 0; (*ConfigInfo->AccessRanges)[i].RangeLength = 0;
(*ConfigInfo->AccessRanges)[i].RangeInMemory = FALSE; (*ConfigInfo->AccessRanges)[i].RangeInMemory = FALSE;
} }
irq = 0;
portBase = 0;
} }
#ifndef UNIATA_CORE #ifndef UNIATA_CORE
} }
@ -2714,6 +2729,34 @@ exit_error:
} // end AtapiFindIsaController() } // end AtapiFindIsaController()
/*
Do nothing, but parse ScsiPort ArgumentString and setup global variables.
*/
ULONG
NTAPI
AtapiReadArgumentString(
IN PVOID HwDeviceExtension,
IN PVOID Context,
IN PVOID BusInformation,
IN PCHAR ArgumentString,
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
OUT PBOOLEAN Again
)
{
#ifndef __REACTOS__
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
#endif
if (AtapiParseArgumentString(ArgumentString, "dump") == 1) {
KdPrint2((PRINT_PREFIX
"AtapiReadArgumentString: Crash dump\n"));
//atapiOnly = FALSE;
g_Dump = TRUE;
}
return(SP_RETURN_NOT_FOUND);
} // end AtapiReadArgumentString()
ULONG ULONG
NTAPI NTAPI
UniataAnybodyHome( UniataAnybodyHome(
@ -3017,7 +3060,7 @@ CheckDevice(
// Issue the ATAPI identify command if this // Issue the ATAPI identify command if this
// is not for the crash dump utility. // is not for the crash dump utility.
try_atapi: try_atapi:
if (!deviceExtension->DriverMustPoll) { if (!g_Dump) {
// Issue ATAPI packet identify command. // Issue ATAPI packet identify command.
if (IssueIdentify(HwDeviceExtension, if (IssueIdentify(HwDeviceExtension,

View file

@ -1,10 +1,10 @@
#define UNIATA_VER_STR "46d7" #define UNIATA_VER_STR "46d8"
#define UNIATA_VER_DOT 0.46.4.7 #define UNIATA_VER_DOT 0.46.4.8
#define UNIATA_VER_MJ 0 #define UNIATA_VER_MJ 0
#define UNIATA_VER_MN 46 #define UNIATA_VER_MN 46
#define UNIATA_VER_SUB_MJ 4 #define UNIATA_VER_SUB_MJ 4
#define UNIATA_VER_SUB_MN 7 #define UNIATA_VER_SUB_MN 8
#define UNIATA_VER_DOT_COMMA 0,46,4,7 #define UNIATA_VER_DOT_COMMA 0,46,4,8
#define UNIATA_VER_DOT_STR "0.46.4.7" #define UNIATA_VER_DOT_STR "0.46.4.8"
#define UNIATA_VER_YEAR 2016 #define UNIATA_VER_YEAR 2016
#define UNIATA_VER_YEAR_STR "2016" #define UNIATA_VER_YEAR_STR "2016"